Archive for the 'School' Category

Semester Wrapup

Sunday, December 16th, 02007

I got an A in my Neural Networks class, keeping my cumulative GPA at 4.04:


screen shot of grades

Here's a screen shot of me working on the final project:


screen shot of of me working on the final Neural Networks Project

I enjoyed the class's back propagation learning assignment. My solution was implemented with Ruby, which resulted in a very elegant implementation (IMHO).

Gnuplot’s epslatex terminal for PDF LaTeX plots

Sunday, November 11th, 02007

As I mentioned in Fun with Gnuplot, you can use Gnuplot's epslatex terminal to create really nice vector graphics having fonts that exactly match your LaTeX documents. This post describes the general process I follow to accomplish this.

(more...)

Fun with Gnuplot

Thursday, November 8th, 02007

I've created a few plots with Gnuplot this semester that I'm fairly proud of. Three examples are shown below. The inline thumbnails are screen shots of PDF plots. If you click on the image, you'll be taken to the PDF file in all its vector glory.

phi(v)
The mathpazo (Palatino) LaTeX fonts are shown above, but I've also created PDF versions with txfonts (Times) and the the default LaTeX font (Computer Modern) for comparison.


generalization plot


positions of objects in a 2D space

There are two really great things about these plots:

  1. They were created with a completely free / opensource tool chain, and they look quite good.
  2. Using Gnuplot's epslatex color terminal allows me to combine vector EPS output with custom LaTeX post-processing so that, for example, the fonts of the plots exactly match those of my LaTeX documents, including all of the fancy math and other special symbols I can imagine.

The ability to create publication-quality plots like this will be a great benefit when I start working on my MS Thesis in earnest next semester. The process of creating these plots is admittedly somewhat arcane (the subject of an upcoming blog post), but this can be automated with a Makefile, and I think the results are worth the effort.

On top of the UNM Bookstore

Sunday, September 30th, 02007

I made another attempt at acquiring source images for my Thesis on Friday.

The images below were taken on top of the UNM bookstore looking out at the new Architecture building, the Frontier restaurant, and Central Avenue.

Before: 2,336 × 3,504 pixel (~ 8.1 MegaPixel) source images arranged in a 3x15 matrix

MS Thesis Proposal: Parallel Panoramic Photo Mosaics

Sunday, September 16th, 02007

Summary

The digital panoramic photo mosaic process involves taking multiple overlapping source photographs of a scene from slightly different vantage points and then digitally "stitching" these images together to form a single composite image that appears as if is was taken from a higher resolution and a possibly wider angle camera.

An example of photo mosaic of UNM's Zimmerman Library follows. A 2×11 matrix of source photographs is shown, followed by the processed mosaic:

Before: 2,336 × 3,504 pixel (~ 8.1 MegaPixel) source images arranged in a 2x11 matrix
After: photo mosaic: 16,961 × 5,792 pixels (~ 98 MegaPixels)

This 16,961 × 5,792 pixel image is big!

One way to think about its size would be to print it out at a relatively standard 200 pixels per inch. If you did so, the print would about 7 × 2.4 feet.

Another way to think its size is to look at a small 100%-scale cropped portion of the image like the one shown below:



If you look carefully, you can see this student crossing the plaza in the right hand portion of the full mosaic.

For full-resolution high-quality output, creating one of these composite panoramas is not a trivial computational task. An example like the one shown above can take hours on a modern workstation, while processing extremely large examples like Max Lyon's GigaPixel image can take many days.

I propose an MS Thesis that will demonstrate how the performance of digital panoramic photo mosaic compositing can be improved through parallel computing. The goal will be to take a multi-day real-world serial example and after writing parallel modifications to existing serial codes, accomplish the same task much quicker in parallel (given access to sufficient computational resources).

(more...)

Grad School Curriculum Update

Thursday, August 23rd, 02007

Fall 2007 semester classes started for me on Tuesday.

My Grad School Curriculum page has been updated to show:

  • I'm taking ECE 547 (Neural Networks) with Thomas Caudell this semester
  • I'm taking 3 credits of ECE 599 (MS Thesis) with Greg Heileman this semester
  • I'm finishing my thesis next semester (Spring 2008) with three more credits of ECE 599
  • I'm hoping to get CS 481 (Operating System Principles) to apply as a credit for my Computational Science and Engineering Certificate Program elective. At least one professor has recommended that this be allowed, so we'll see. If it's not allowed as an elective, I'll try and also take CS 564 - Introduction to Database Management in the Spring 2008 semester, if it's offered.

Important next steps:

  • Get my "Program of Studies for Master's Degree" form submitted and approved.
  • Get my thesis proposal in a fair state
  • Meet with Dr. Heileman regarding the thesis

If everything works out, I'll have my MS is May 2008.

The 4.0 Continues

Sunday, May 13th, 02007

Strangely the cumulative GPA doesn't reflect this new A. Seems like fairly serious breakage to me.

The curriculum page has been updated. I'll most likely be taking ECE 547 - Neural Networks with Thomas Caudell in the Fall.

Update: On Tuesday I got the following message explaining the GPA stuff:

to		STUMESSAGES-L@list.unm.edu
date		May 15, 2007 2:14 PM
subject		[STUMESSAGES-L] Spring Semester Cumulative GPA Calculation
	
Dear UNM Student,
	
For your information Spring 2007 GPA (Grade Point Average)information will
be calculated into your Cumulative GPA officially on the evening of May 23.
If you believe your GPA is incorrect after this date, you may contact the
Registrar's Office for more information.

Embarrassing.

UNM could really, really use some serious process improvement.

Another Semester Down

Wednesday, May 9th, 02007

I submitted the final assignment for CS522 yesterday, after sitting in front of a screen that looks something like the following for more than a good while (click on image for full size version):



The result of this particular assignment was a forward and reverse Daubechies 4 Wavelet transform implemented in Scheme (UNM Scheme specifically).

CVS to SVN Migration Notes

Saturday, April 7th, 02007

I've been using Subversion (wikipedia page, reference) for much of my SCM needs at work and at home for quite a while now, but I was still using a few CVS repositories hosted at bohnsack.com that needed to be accessed from many locations (e.g., a repository for my grad school files).

This morning I decided to migrate these last few personal CVS repositories to SVN and while I was at it, create a new SVN repository on bohnsack.com for a collaborative effort I'm working on (more than one person will need to access it).

Here are some notes from the experience, split up into four major parts:

  1. Installing SVN software on the server
  2. Migrating existing personal CVS repositories to SVN
  3. Creating a new SVN repository that's meant to be shared by more than one person
  4. Setting up email commit notifications
  5. Backing up the SVN repositories using svnsync

Step #1: Install the latest SVN software

First, I installed all the most recent SVN tools on bohnsack.com, which currently runs RHEL3. Checking out available packages from here and more specifically here, the installation process went something like this:

# get the files
downloadsite="http://summersoft.fay.ar.us/pub/subversion/latest/rhel-3/i386"
wget ${downloadsite}/subversion-1.4.3-1.i386.rpm
wget ${downloadsite}/cvs2svn-1.2.1-1.noarch.rpm
wget ${downloadsite}/httpd-2.0.46-61.1.ent.i386.rpm
wget ${downloadsite}/httpd-devel-2.0.46-61.1.ent.i386.rpm
wget ${downloadsite}/mod_dav_svn-1.4.3-1.i386.rpm
wget ${downloadsite}/mod_ssl-2.0.46-61.1.ent.i386.rpm
wget ${downloadsite}/neon-0.24.7-1.i386.rpm
wget ${downloadsite}/subversion-devel-1.4.3-1.i386.rpm
wget ${downloadsite}/subversion-perl-1.4.3-1.i386.rpm
wget ${downloadsite}/subversion-python-1.4.3-1.i386.rpm
wget ${downloadsite}/subversion-tools-1.4.3-1.i386.rpm
wget ${downloadsite}/neon-devel-0.24.7-1.i386.rpm
	
# install them
rpm -ivh httpd-2.0.46-61.1.ent.i386.rpm httpd-devel-2.0.46-61.1.ent.i386.rpm \
mod_ssl-2.0.46-61.1.ent.i386.rpm mod_dav_svn-1.4.3-1.i386.rpm \
subversion-1.4.3-1.i386.rpm subversion-devel-1.4.3-1.i386.rpm  \
neon-devel-0.24.7-1.i386.rpm neon-0.24.7-1.i386.rpm \
subversion-perl-1.4.3-1.i386.rpm subversion-python-1.4.3-1.i386.rpm \
cvs2svn-1.2.1-1.noarch.rpm

Although I needed the libraries provided by the installed httpd software, I didn't want it to actually run, so the newly installed webserver was shutdown and prevented from starting at boot time:

chkconfig httpd off
/etc/init.d/httpd stop

Step #2 CVS to SVN Migration

I had two personal CVS repositories to migrate. A step-by-step process for one of them is shown below:

Migrate the repository

# Create a directory for the SVN repository to live in
mkdir -p /home/user1/svn/repos/
	
# Specify local CVS/SVN repositories
cvsrepo=/home/user1/cvsroot/UNM-files/
svnrepo=/home/user1/svn/repos/UNM-files
	
# See if the migration tool works
cvs2svn --dry-run -s ${svnrepo} ${cvsrepo}
	
# Actually do the migration
cvs2svn -s ${svnrepo} ${cvsrepo}
.
.
Starting Subversion commit 1049 / 1050
Starting Subversion commit 1050 / 1050
Done.
	
cvs2svn Statistics:
------------------
Total CVS Files:              2415
Total CVS Revisions:          4129
Total Unique Tags:               1
Total Unique Branches:           1
CVS Repos Size in KB:       604725
Total SVN Commits:            1050
First Revision Date:    Tue Jan 25 21:17:41 2005
Last Revision Date:     Sat Apr  7 11:00:03 2007
------------------
Timings:
------------------
pass 1:    24 seconds
pass 2:     0 seconds
pass 3:     0 seconds
pass 4:     0 seconds
pass 5:     1 second
pass 6:     0 seconds
pass 7:     0 seconds
pass 8:   500 seconds
total:    528 seconds

Checkout working copy of new repository

cd /home/user1/rcs/
	
# if checking out files on a different host than the one that hosts the repo
svn co svn+ssh://user1@bohnsack.com:/home/user1/svn/repos/UNM-files
	
# if checking out files on the same host that hosts the repo
svn co file:///home/user1/svn/repos/UNM-files

For the remote checkout option to work, ssh to the remote host must be possible. For it to be convenient, you'll probably want to setup an ssh public key pair.

Take care of .cvsignore migration

With this reference:

# cd into checked SVN working copy directory
cd /home/user1/rcs/UNM-files
	
# translate .cvsignore to svn propset
find -name .cvsignore | while read file; do
    svn propset svn:ignore "`cat "$file"`" "`echo "$file" | sed 's,/[^/]*$,,'`"
done
	
# remove .cvsignore files
svn rm `find -name .cvsignore |xargs`
	
# commit
svn commit -m "migrate .cvsignore information to SVN"

Step #3: Setup Shared Repository

It's possible to setup a really slick shared SVN repository with Apache and WebDAV, but I choose to keep things really simple with some simple Linux system administration and the svn+ssh access method. The SVN book covers lots of different ways to do this kind of shared repository, but this is how I did it:

Create users, groups, and repository

projectname="foobar"
newuser="newuser"
	
# create new group and user
groupadd ${newuser}
useradd -g ${newuser} ${newuser}
	
# create project group and add me a new user to this group
groupadd ${projectname}
	
# use vi on /etc/group to add user1 (me) and ${newuser}
# to the ${projectname} group
	
# create repo directory with suitable name, ownership, and setgid bit
mkdir -p cd /usr/local/svn/repos/
chmod 777 /usr/local/svn/
chmod 777 /usr/local/svn/repos
svnadmin create --fs-type fsfs /usr/local/svn/repos/${projectname}
chown -R bohnsack:${projectname} /usr/local/${projectname}
cd /usr/local/svn/repos/
find ${projectname} -type f | xargs chmod g+rw
find ${projectname} -type d| xargs chmod g+rwx
find ${projectname} -type d| xargs chmod g+s
find ${projectname} | xargs chmod o-rwx

Set umask

I want newly created files to be readable and writable by the user and group but not anyone else. An easy was to accomplish this was adding the following to each user's ~/.bashrc:

umask 007

A much better solution would be for svnserve to set this SVN-specific umask at invocation time and leave the users' general umasks alone. This is undoubtedly possible.

Create some files to import

From a remote host:

projectname="foobar"
cd /home/user1/rcs
mkdir ${projectname}
cd ${projectname}
mkdir trunk
mkdir branches
mkdir tags
svn import -m "initial files" \
svn+ssh://user1@bohnsack.com/usr/local/svn/repos/${projectname}
cd ..
rm -rf ${projectname}
svn co svn+ssh://user1@bohnsack.com/usr/local/svn/repos/${projectname}

Step #4: Commit Notifications

For shared repositories, it's nice to know what the other people iwth write access are up to. One really good way to accomplish this is to install a post-commit hook to send out email with diffs. I'm using SVN::Notify (Author's home page, example output)

perl -MCPAN  -e 'install SVN::Notify'

Then, modify hooks/post-commit to be something like this for each repository you want email notifications for:

REPOS="$1"
REV="$2"
	
/usr/bin/svnnotify --repos-path "$REPOS" --revision "$REV" \
  --to             "user1@bohnsack.com, user2@otherplace.com" \
  --from           "user1@bohnsack.com"                 \
  --reply-to       "user1@bohnsack.com"                 \
  --subject-prefix "[SVN UNM-Files]"                       \
  --subject-cx                                             \
  --svnlook        /usr/bin/svnlook                        \
  --sendmail       /usr/sbin/sendmail                      \
  --handler        Alternative                             \
  --alternative    HTML::ColorDiff                         \
  --with-diff

Step #5: Backups

Wanting to take advantage of my at-home RAIDed ReadyNAS as one backup of these important files, I wrote the following scripts to sync these repositories from bohnsack.com to the NAS:

Initial Setup

#!/bin/bash -x
# init-remote-svn-sync-repos.sh
	
localdir=/readynas/data_files/svn/repos
personalrepos="UNM-files otherrepo"
sharedrepos="foobar"
	
for repo in $personalrepos $sharedrepos
do
  svnadmin create --fs-type fsfs ${localdir}/${repo}
  echo "#!/bin/sh" > ${localdir}/${repo}/hooks/pre-revprop-change
  chmod +x ${localdir}/${repo}/hooks/pre-revprop-change
done
	
for repo in $personalrepos
do
  svnsync init \
  file://${localdir}/${repo} \
  svn+ssh://user1@bohnsack.com/home/user1/svn/repos/${repo}
done
	
for repo in $sharedrepos
do
  svnsync init \
  file://${localdir}/${repo} \
  svn+ssh://user1@bohnsack.com/usr/local/svn/repos/${repo}
done

Subsequent Syncing

#!/bin/bash -x
# svn-sync.sh
	
localdir=/readynas/data_files/svn/repos
personalrepos="UNM-files other-repos"
sharedrepos="foobar"
	
for repo in $personalrepos $sharedrepos
do
  svnsync sync file://${localdir}/${repo}
done

Fall 2006 Grades

Monday, December 18th, 02006

Despite receiving a humbling B+ in ECE 537, I still managed to maintain a higher than 4.0 cumulative GPA (4.04), by picking up my third A+ at UNM with Math 471:

Name: Matthew P. Bohnsack
Term: Fall 2006
Degree: Master of Science
Major: Electrical Engineering
Level: Graduate/GASM

Subject Course Course Title Final Grade GPA Hours Quality Points
ECE 537 Foundations of Computing B+ 3.000 9.99
MATH 471 Introduction to Scientific Computing A+ 3.000 12.99

  Attempted Earned GPAHours Quality Points GPA
Current Term: 6.000 6.000 6.000 22.98 3.83
Cumulative: 22.000 22.000 21.000 84.96 4.04

Some of my output:

This leaves only two more classes and my thesis. See my curriculum entry for more detail on the classes.

The plan is to take two classes next semester, then work on the thesis over the summer and into the fall 2007 semester if needed.

I have preliminarily found an advisor and a topic for my thesis. I'll have more detail on the thesis proposal up soon.

Nesting

Sunday, September 24th, 02006

This semester is proving quite challenging.

Elisa calls the following resultant behavior "nesting":

nesting

Things looked similar last year around this time, but only two more classes after this semester... right?

Spring 2006 Grades

Friday, June 2nd, 02006

I ended up with two A+ grades this semester, bringing my cumulative GPA to 4.13:



My curriculum page has been updated to reflect these grades and the classes I'll be taking next semester:

  ECE 537 - Foundations of Computing
  Math 471 - Introduction to Scientific Computing.

All the A+

Wednesday, May 17th, 02006

Evidently, one can achieve an A+ at UNM.

CS481 - Operating System Principles - Final Grade
Last First Total Hwk1 Hwk2 Hwk3 Hwk4 Hwk5 Proj1 Proj2 Proj3 Midterm Grade Rank
Maximum: 1394 110 107 100 100 100 100 100 100 577
Bohnsack Matthew 1286 100 105 100 93 100 96 100 90 502 A+ 1
Total 14911 1096 1164 1100 1212 1259 998 1318 984 5780
Average 828.39 60.89 64.67 61.11 67.33 69.94 55.44 73.22 54.67 321.11
Max 1286 100 105 100 100 100 97 100 90 505
Min 699 34 0 0 0 0 31 70 0 165
SD 170.6 18.91 26.49 42.58 25.18 27.13 19.36 9.3 33.58 82.45
Median 1101.5 83.5 89 100 92 100 72 100 88 423.5

Spring 2006 Semester is Complete

Friday, May 5th, 02006

The Spring 2006 semester is finally complete. Wow -- that was a lot of work. Highlights:

  • Wrote non-trivial MPI codes and ran them with good results on big machines.
  • Wrote parallel Pthreads codes and ran them on shared memory SMP systems.
  • Wrote a number of Linux kernel modules.
  • Did a fair amount of systems programming in C.
  • Wrote a good number of reports.
  • Polished my MATLAB skills -- especially graphing (though I'd like to also explore GNUPlot some more as an alternative)
  • Became pretty proficient in LaTeX

In general, a very fruitful session this time. For reference, some of my output:

DiffEq Kung Fu

Thursday, April 27th, 02006

Elisa got an A in her Differential Equations class this semester. Impressive — Most impressive! I was only able to muster a B:

Matthew Bohnsack's NIACC Transcript, including a B in DiffEq

CS 442 Project #1: Sieve of Eratosthenes

Monday, February 13th, 02006

The first programming assignment for my parallel processing class is an implementation of the Sieve of Eratosthenes with MPI on a parallel machine.

Fun!

References:

The serial algorithm in Ruby:

#!/usr/bin/ruby -w
max = Integer(ARGV.shift || 100)
	
sieve = [nil, nil] + (2 .. max).to_a
	
(2 .. Math.sqrt(max)).each do |i|
  next unless sieve[i]
  (i*i).step(max, i) do |j|
    sieve[j] = nil
  end
end
	
puts sieve.compact.join(", ")

Homework in LaTeX

Thursday, February 9th, 02006

I've had a collection of unread LaTeX texts on my bookshelf for a damn log time. What... ten years?

This semester however, I buckled down and started using it (TeX not the books) for classwork. i.e., I got it done. The first showing is my submission for CS 481 Homework #1. You can check it out here.

It turned out pretty smooth. The diagrams are a little weak, but TeX has the power, and I'll get similar diagrams done beautifully, the next time I have the opportunity to play with all the possibilities.

One interesting thing about the experiment is that I found myself having no need for any of those crusty reference books. Today's Internet, Google, and other people's example markup was all I needed to get it done. Sweet!

bohnsack_cs481_s2006_hw01.pdf

Valgrind is the greatest

Sunday, February 5th, 02006

Specific instruction #6 for CS 481 Project #1: "Avoid memory leaks in your program."

Valgrind to the rescue...

Before:

==31405== ERROR SUMMARY: 720 errors from 2 contexts (suppressed: 11 from 1)
==31405==
...
==31405== malloc/free: in use at exit: 17,280 bytes in 720 blocks.
==31405== malloc/free: 5,770 allocs, 5,050 frees, 54,595 bytes allocated.
...
==31405== LEAK SUMMARY:
==31405==    definitely lost: 17,280 bytes in 720 blocks.
==31405==      possibly lost: 0 bytes in 0 blocks.
==31405==    still reachable: 0 bytes in 0 blocks.
==31405==         suppressed: 0 bytes in 0 blocks.

After:

==7634== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 1)
==7634== No malloc'd blocks -- no leaks are possible.

Ahhhhh... Bye bye memory leaks.

Does a child process get a copy of its parent’s stack?

Tuesday, January 24th, 02006

Today in operating systems class, the following question came up:

Does a Linux child process get a copy of its parent's stack?

I said yes, based on the rationale that child processes couldn't return from nested function calls without copies of their parent's stack.

I built the following experiment to find out what really happens. The results seem to indicate that I was right...

Code (forkexample.c):

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
	
void foo(void);
void bar(void);
void biz(void);
	
pid_t  child_pid;
	
int main(int argc, char *argv[])
{
  pid_t pid;
  int   child_exit_status;
	
  foo();
  printf("Both parent & child should get here - PID: %d\n", getpid());
	
  if(getpid() == child_pid)
  {
    return 0; /* only the child exits here */
  }
	
  /* block until child returns */
  pid = waitpid(child_pid, &child_exit_status, WNOHANG);
	
  printf("Only parent should be here - PID: %d\n", getpid());
	
  return 0;
}
	
void foo(void)
{
  printf("Entering foo() as PID: %d\n", getpid());
  bar();
  printf("Exiting foo() as PID: %d\n", getpid());
}
	
void bar(void)
{
  printf("Entering bar() as PID: %d\n", getpid());
  biz();
  printf("Exiting bar() as PID: %d\n", getpid());
}
	
void biz(void)
{
  printf("Entering biz() as PID: %d\n", getpid());
  if ((fork() == 0))
  {
    child_pid = getpid();
    printf("I am the child.  PID: %d\n", getpid());
  }
  else
  {
    printf("I am the parent.  PID: %d\n", getpid());
  }
  printf("Exiting biz() as PID: %d\n", getpid());
}

Compile:

gcc -Wall forkexample.c -o forkexample

Run:

$ ./forkexample
Entering foo() as PID: 12084
Entering bar() as PID: 12084
Entering biz() as PID: 12084
I am the child.  PID: 12085
Exiting biz() as PID: 12085
Exiting bar() as PID: 12085
Exiting foo() as PID: 12085
Both parent & child should get here - PID: 12085
I am the parent.  PID: 12084
Exiting biz() as PID: 12084
Exiting bar() as PID: 12084
Exiting foo() as PID: 12084
Both parent & child should get here - PID: 12084
Only parent should be here - PID: 12084

As you can see, the child process successfully rolls back the call stack - way past the function it was forked in. It seems to me that this would be impossible, if it didn't have a copy of its parent's stack.

First Day of School Tomorrow

Monday, January 16th, 02006

See here for details.