<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Kered.org/Blog &#187; programming</title>
	<atom:link href="http://kered.org/blog/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://kered.org/blog</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Mon, 26 Apr 2010 21:25:49 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Calculating PI</title>
		<link>http://kered.org/blog/2010-03-14/calculating-pi/</link>
		<comments>http://kered.org/blog/2010-03-14/calculating-pi/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 04:52:48 +0000</pubDate>
		<dc:creator>derek</dc:creator>
				<category><![CDATA[math]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://kered.org/blog/?p=187</guid>
		<description><![CDATA[In honor of PI day, I thought I would recall a story of my wayward youth.  =P
In middle school (at JDMS), I was becoming decently proficient at everything BASIC.  (Apple II, TRS-80 and DOS 3.3)  One of my math teachers mentioned to me that you could approximate PI by filling one quarter of a circle with an ever increasing [...]]]></description>
			<content:encoded><![CDATA[<p>In honor of PI day, I thought I would recall a story of my wayward youth.  =P</p>
<p>In middle school (at <a href="http://maps.google.com/maps?ie=UTF8&amp;q=jamesville+dewitt+middle+school&amp;fb=1&amp;gl=us&amp;hq=dewitt+middle+school&amp;hnear=jamesville&amp;cid=0,0,12813749139930060848&amp;ei=PbqdS6b0B8KUtgeC75CHBg&amp;ved=0CAoQnwIwAA&amp;ll=43.032102,-76.084485&amp;spn=0.013081,0.026522&amp;z=15&amp;iwloc=A">JDMS</a>), I was becoming decently proficient at everything BASIC.  (Apple II, TRS-80 and DOS 3.3)  One of my math teachers mentioned to me that you could approximate PI by filling one quarter of a circle with an ever increasing number of rectangles of smaller and smaller widths.  And so I wrote a program to do just that.  Spent weeks running and rerunning it with different numbers of slices (and different methods of calculating the heights) and comparing the outputs to official known good values.  (and charting my accuracy)</p>
<p>I don&#8217;t remember exactly how accurate I finally got before they told me to stop running multi-day processes on the lab computers&#8230;  But suffice it to say: I was VERY nerdy.  =P</p>
]]></content:encoded>
			<wfw:commentRss>http://kered.org/blog/2010-03-14/calculating-pi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Where&#8217;s My Car? for Palm Pre/Pixi</title>
		<link>http://kered.org/blog/2010-03-04/wheres-my-car/</link>
		<comments>http://kered.org/blog/2010-03-04/wheres-my-car/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 03:14:15 +0000</pubDate>
		<dc:creator>derek</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://kered.org/blog/?p=149</guid>
		<description><![CDATA[I&#8217;ve submitted my first WebOS application to their App Store!
Where&#8217;s My Car? helps you find your car in a crowded parking lot. When you leave your car, simply open the application. (It will automatically get your current GPS location) Leave the application open, and when you&#8217;re done doing whatever it is you have to do, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve submitted my first WebOS application to their App Store!</p>
<blockquote><p>Where&#8217;s My Car? helps you find your car in a crowded parking lot. When you leave your car, simply open the application. (It will automatically get your current GPS location) Leave the application open, and when you&#8217;re done doing whatever it is you have to do, click &#8220;Take Me To It!&#8221; An arrow will show up (as well as a distance measurement). Simply walk in the direction of the arrow, and you&#8217;ll be quickly guided back to your car! BTW, I originally wrote this app as a present for my wife. <img src='http://kered.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  I&#8217;ve decided to place it on the App Store as a FREE app because I don&#8217;t see why the other apps that do the same thing charge $5 for such a simple feature. Let me know if you like it! <img src='http://kered.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p></blockquote>
<p><strong>UPDATE:</strong> It has been approved/published!  To download, open the App Catalog.  Search for &#8220;car&#8221;.  Click the coins icon in the lower-right to show only FREE apps, and &#8220;Where&#8217;s My Car?&#8221; should be the first in the list!  :)</p>
<p><strong>UPDATE 2:</strong> Click here to download:  <a href="http://developer.palm.com/appredirect/?packageid=org.kered.wheresmycar">Where&#8217;s My Car?</a></p>
<p>Screenshots after the break&#8230;</p>
<p><span id="more-149"></span></p>
<p><a href="http://kered.org/blog/wp-content/uploads/2010/03/wheresmycar_1.png"><img class="alignnone size-full wp-image-151" title="wheresmycar_1" src="http://kered.org/blog/wp-content/uploads/2010/03/wheresmycar_1.png" alt="" width="320" height="480" /></a></p>
<p><a href="http://kered.org/blog/wp-content/uploads/2010/03/wheresmycar_2.png"><img class="alignnone size-full wp-image-152" title="wheresmycar_2" src="http://kered.org/blog/wp-content/uploads/2010/03/wheresmycar_2.png" alt="" width="320" height="480" /></a></p>
<p><a href="http://kered.org/blog/wp-content/uploads/2010/03/wheresmycar_3.png"><img class="alignnone size-full wp-image-153" title="wheresmycar_3" src="http://kered.org/blog/wp-content/uploads/2010/03/wheresmycar_3.png" alt="" width="320" height="480" /></a></p>
<p><a href="http://kered.org/blog/wp-content/uploads/2010/03/wheresmycar_4.png"><img class="alignnone size-full wp-image-154" title="wheresmycar_4" src="http://kered.org/blog/wp-content/uploads/2010/03/wheresmycar_4.png" alt="" width="320" height="480" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://kered.org/blog/2010-03-04/wheres-my-car/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dependency Injection: Coke with Lime</title>
		<link>http://kered.org/blog/2010-01-29/dependency-injection-coke-with-lime/</link>
		<comments>http://kered.org/blog/2010-01-29/dependency-injection-coke-with-lime/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 17:51:11 +0000</pubDate>
		<dc:creator>derek</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[stupid]]></category>

		<guid isPermaLink="false">http://kered.org/blog/?p=148</guid>
		<description><![CDATA[I have in the past expressed skepticism regarding the utility of Spring&#8217;s XML-based dependency injection configuration files.  A bit ago, in one of these conversations, I was pointed to Martin Fowler&#8217;s article on dependency injection.  I found it hilarious.

One of the interesting aspects of the academic side of computer science is the creation [...]]]></description>
			<content:encoded><![CDATA[<p>I have in the past expressed skepticism regarding the utility of Spring&#8217;s XML-based dependency injection configuration files.  A bit ago, in one of these conversations, I was pointed to Martin Fowler&#8217;s article on <a href="http://martinfowler.com/articles/injection.html">dependency injection</a>.  I found it hilarious.</p>
<p><span id="more-148"></span></p>
<p>One of the interesting aspects of the academic side of computer science is the creation if new terms for old ideas.  Take a well known concept, add a twist of lime, invent a new term, throw in a little obfuscation, and presto &#8211; an instant publishable paper (as long as you&#8217;re not submitting to a top-tier journal).  It&#8217;s publishable because it&#8217;s very hard to classify between these junk papers and complicated but genuinely new concepts.  (so hard in fact many journals don&#8217;t even try &#8211; even nonsensical papers can occasionally <a href="http://www.the-scientist.com/blog/display/55756/">sneak through</a>)  And since people are judged on how many papers they produce, this problem has become an epidemic.  The signal to noise ratio is currently mind-bogglingly low.</p>
<p>Dependency Injection I&#8217;m now certain is the corporate equivalent of this academic phenomenon.  While people many not have as much incentive without the threat of not getting tenure due to too few papers published, the fame of being the guy who invented The Next Big Thing(tm) is non-trivial.  And even if you don&#8217;t invent it yourself, being an early champaign of The Next Big Thing(tm) distinguishes yourself from your peers, helps you land new contracts, etc.  In a myriad of career enhancing ways it&#8217;s still a viable incentive.</p>
<p>Not to say it&#8217;s a con-job mind you.  Buzz-words are everywhere in this business.  It&#8217;s exciting to be on the cutting edge, and it&#8217;s hard to separate out the true leading fronts from the fake ones. It&#8217;s real easy to get swept up in the excitement.  (I&#8217;ve been guilty of it myself on more than one occasion)  But that doesn&#8217;t change the basic question.</p>
<p>So&#8230; Dependency Injection:  A new idea or Coke with Lime?</p>
<p>Let&#8217;s start with Martin&#8217;s own sample code.</p>
<pre><code>class MovieLister...
    private MovieFinder finder;
    public MovieLister() {
        finder = new ColonDelimitedMovieFinder("movies1.txt");
    }
    public Movie[] moviesDirectedBy(String arg) {
        List allMovies = finder.findAll();
        for (Iterator it = allMovies.iterator(); it.hasNext();) {
            Movie movie = (Movie) it.next();
            if (!movie.getDirector().equals(arg)) it.remove();
        }
        return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);
    }</code></pre>
<p>The method <code>moviesDirectedBy</code> uses an interface:</p>
<pre><code>public interface MovieFinder {
    List findAll();
}</code></pre>
<p>Look at the MovieListener constructor.  Martin argues that it&#8217;s a bad implementation because it ties the MovieListener class to a specific implementation of a MovieFinder.  And he&#8217;s absolutely right.  It&#8217;s pointless to have a MovieFinder interface if your code can only ever use one instance of it.</p>
<p>But this is not a new concept.  This is the very basis of object-oriented programming.  He may as well have called Dependency Injection &#8220;Non-Retarded Programming&#8221;.  A non-retard implementation would probably contain this:</p>
<pre><code>    public MovieLister(MovieFinder finder) {
        this.finder = finder;
    }</code></pre>
<p>Which, low and behold, is exactly what he recommends.  His example is nothing but a <a href="http://en.wikipedia.org/wiki/Straw_man">straw-man argument</a>.</p>
<p>So my question to you is this:  When did having a constructor that takes an argument become a new idea worthy of a new term?  I wrote Java programs in 1996 that did this.  C++ did it long before that.  I mean good god, this idea is as old as object-oriented programming itself.</p>
<p>Now if you&#8217;re using the Spring framework, you might write some controlling XML not unlike the following:</p>
<pre><code>&lt;bean id="ColonDelimitedMovieFinder" class="org.kered.ColonDelimitedMovieFinder"&gt;
    &lt;constructor-arg index="0" ref="movies1.txt"/&gt;
&lt;/bean&gt;
&lt;bean id="MovieLister" class="org.kered.MovieLister"&gt;
    &lt;constructor-arg index="0" ref="ColonDelimitedMovieFinder"/&gt;
&lt;/bean&gt;
</code></pre>
<p>And then the Spring controller would parse this XML, generate your objects, and offer some lookup service to some other code that uses MovieListener.  But I ask you this:  Why do you need a framework for that?  How is this XML any less complicated than actual Java code that does the same thing?  For example:</p>
<pre><code>
public class MyController {
  private static MovieFinder finder = new ColonDelimitedMovieFinder("movies1.txt");
  private static MovieListener listener = new MovieListener(finder);
  public static getMovieListener() { return listener; }
}
</code></pre>
<p>Presto &#8211; no framework needed!  Plus, you&#8217;ve not given up compile-time validity checking of your code.  (I love the &#8220;rename class&#8221; feature of Eclipse &#8211; too bad it breaks hard when all your inter-class ties are defined in XML configuration files.  Back to using grep on every rename&#8230;)</p>
<p>Now, one might argue that the XML configuration gives you run-time flexibility in your architecture.  That it allows non-programmers to configure your application in any way they please.  But this is a fallacy.  These XML configuration files *are* quasi-programming languages (interpreted ones at that).  All you&#8217;re saving is the compile.  You still have to be a programmer to modify them.  It is no simpler than modifying the Java source code directly (or the bash/bat script that launches it).  You&#8217;re simplifying nothing &#8211; only shifting the location of the complexity.</p>
<blockquote><p>Ok Derek, yes, I can&#8217;t have my users editing the spring application context files themselves.  But I still need to deploy multiple configurations of my architecture that vary significantly.  How do I do that when it&#8217;s statically compiled?</p></blockquote>
<p>Simple. Create multiple &#8220;controller&#8221; classes.  (in a 1-to-1 parallel to whatever XML you would have to write anyway)  Switch between them with runtime parameters, or a one-line configuration option.  Again, Programming 101.  And as a bonus, you get to fix the possible number of deployable configurations to a number that&#8217;s economically testable, and you prevent the setup of nonsensical configurations.</p>
<blockquote><p>But Derek, in your example, &#8220;movies1.txt&#8221; is hard-coded into your program.</p></blockquote>
<p>Yes, but &#8220;movies1.txt&#8221; is hard-coded into *both* examples.  No application is going to instruct the user to modify that blob of XML either.  Both systems would need an additional config file or gui somewhere to expose that option to the user.</p>
<p>To recap:  I&#8217;m not saying dependency injection is crap.  In fact I&#8217;ve apparently been programming it for over a decade.  I&#8217;m just saying it&#8217;s a vacant term that offers nothing new to the field of computer science.  And I&#8217;m saying that Spring&#8217;s XML configuration for dependency injection offers you virtually nothing in terms of ease of configuration (except for it being run-time interpreted, which you can get in a variety of simpler ways), and destroys one of Java&#8217;s greatest assets: strong compile time validity testing.  (And if you don&#8217;t care about that, why are you using Java?  Go learn Python!)</p>
<p><strong>Update:</strong>  Check out <a href="http://code.google.com/p/unsprung/">http://code.google.com/p/unsprung/</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://kered.org/blog/2010-01-29/dependency-injection-coke-with-lime/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Brain-Dead</title>
		<link>http://kered.org/blog/2009-12-21/brain-dead/</link>
		<comments>http://kered.org/blog/2009-12-21/brain-dead/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 19:38:34 +0000</pubDate>
		<dc:creator>derek</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[stupid]]></category>

		<guid isPermaLink="false">http://kered.org/blog/?p=141</guid>
		<description><![CDATA[Java is somewhat brain-dead at times.  For instance:
while(c=System.in.read()>-1){
  System.out.print(backspaceChar);
}
Doesn&#8217;t do what you&#8217;d expect.  (hide console input)  It appears that System.in is being silently buffered.
So a little googling: http://java.sun.com/developer/technicalArticles/Security/pwordmask/
Sun&#8217;s recommendation is a busy-wait loop in a separate thread that constantly rewrites the previous character?!?  I mean, seriously, WTF?!?
Edit: It looks like [...]]]></description>
			<content:encoded><![CDATA[<p>Java is somewhat brain-dead at times.  For instance:</p>
<pre><code>while(c=System.in.read()>-1){
  System.out.print(backspaceChar);
}</code></pre>
<p>Doesn&#8217;t do what you&#8217;d expect.  (hide console input)  It appears that System.in is being silently buffered.</p>
<p>So a little googling: <a href="http://java.sun.com/developer/technicalArticles/Security/pwordmask/">http://java.sun.com/developer/technicalArticles/Security/pwordmask/</a></p>
<p>Sun&#8217;s recommendation is a busy-wait loop in a separate thread that constantly rewrites the previous character?!?  I mean, seriously, WTF?!?</p>
<p>Edit: It looks like Sun implemented a new API for non-echoing prompts in v1.6:  <a href="http://java.sun.com/javase/6/docs/api/java/io/Console.html">http://java.sun.com/javase/6/docs/api/java/io/Console.html</a></p>
<p>But this is still crappy.  Introducing a new API to partially work around the broken functionality of an old API is how you get bloated monstrosities to begin with.</p>
]]></content:encoded>
			<wfw:commentRss>http://kered.org/blog/2009-12-21/brain-dead/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XiMpLode</title>
		<link>http://kered.org/blog/2009-07-29/ximplode/</link>
		<comments>http://kered.org/blog/2009-07-29/ximplode/#comments</comments>
		<pubDate>Wed, 29 Jul 2009 17:53:36 +0000</pubDate>
		<dc:creator>derek</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[stupid]]></category>

		<guid isPermaLink="false">http://kered.org/blog/?p=126</guid>
		<description><![CDATA[It has been said before, but it deserves repeating:  XML is overused.  And often, made unnecessarily over-complicated for the task.  Take for instance the example &#8220;A Simple Soap Client&#8220;.
Here is the request:
&#60;?xml version="1.0"?&#62;
&#60;SOAP-ENV:Envelope
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" &#62;
  &#60;SOAP-ENV:Body&#62;
    &#60;calculateFibonacci
      xmlns="http://namespaces.cafeconleche.org/xmljava/ch3/"
     [...]]]></description>
			<content:encoded><![CDATA[<p>It has been said before, but it deserves repeating:  XML is overused.  And often, made unnecessarily over-complicated for the task.  Take for instance the example &#8220;<a href="http://www.cafeconleche.org/books/xmljava/chapters/ch03s05.html">A Simple Soap Client</a>&#8220;.</p>
<p>Here is the request:</p>
<pre><code>&lt;?xml version="1.0"?&gt;
&lt;SOAP-ENV:Envelope
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" &gt;
  &lt;SOAP-ENV:Body&gt;
    &lt;calculateFibonacci
      xmlns="http://namespaces.cafeconleche.org/xmljava/ch3/"
      type="xsi:positiveInteger"&gt;10&lt;/calculateFibonacci&gt;
  &lt;/SOAP-ENV:Body&gt;
&lt;/SOAP-ENV:Envelope&gt;</code></pre>
<p>Here is the response:</p>
<pre><code>&lt;?xml version="1.0"?&gt;
&lt;SOAP-ENV:Envelope
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" /&gt;
  &lt;SOAP-ENV:Body&gt;
    &lt;Fibonacci_Numbers
      xmlns="http://namespaces.cafeconleche.org/xmljava/ch3/"&gt;
      &lt;fibonacci index="1"&gt;1&lt;/fibonacci&gt;
      &lt;fibonacci index="2"&gt;1&lt;/fibonacci&gt;
      &lt;fibonacci index="3"&gt;2&lt;/fibonacci&gt;
      &lt;fibonacci index="4"&gt;3&lt;/fibonacci&gt;
      &lt;fibonacci index="5"&gt;5&lt;/fibonacci&gt;
      &lt;fibonacci index="6"&gt;8&lt;/fibonacci&gt;
      &lt;fibonacci index="7"&gt;13&lt;/fibonacci&gt;
      &lt;fibonacci index="8"&gt;21&lt;/fibonacci&gt;
      &lt;fibonacci index="9"&gt;34&lt;/fibonacci&gt;
      &lt;fibonacci index="10"&gt;55&lt;/fibonacci&gt;
    &lt;/Fibonacci_Numbers&gt;
  &lt;/SOAP-ENV:Body&gt;
&lt;/SOAP-ENV:Envelope&gt;</code></pre>
<p>Dear $DEITY, why do we need to define a new data type to hold a list of integers?  And what in the world is that &#8220;index&#8221; attribute doing there?  IT&#8217;S A FUCKING LIST.  This is like a real-life example of the old XML binary encoding joke:</p>
<pre><code>&lt;data&gt;
  &lt;binary&gt;
    &lt;bit index="0"&gt;0&lt;/bit&gt;
    &lt;bit index="1"&gt;0&lt;/bit&gt;
    &lt;bit index="2"&gt;1&lt;/bit&gt;
    ...
    &lt;bit index="n"&gt;1&lt;/bit&gt;
  &lt;/binary&gt;
&lt;/data&gt;</code></pre>
<p>It&#8217;s just sad&#8230;</p>
<p>For the sake of it, let&#8217;s compare to a JSON-RPC version:  (not the epitome of efficiency mind you, but an order of magnitude better)</p>
<pre><code>--> { "method": "calculateFibonacci", "params": [10,], "id": 1}
<-- { "result": [1,1,2,3,5,8,13,21,34,55], "error": null, "id": 1}</code></pre>
<p>Which would you rather use?  <img src='http://kered.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://kered.org/blog/2009-07-29/ximplode/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Easy Python/Numpy CUDA/CUBLAS Integration</title>
		<link>http://kered.org/blog/2009-04-13/easy-python-numpy-cuda-cublas/</link>
		<comments>http://kered.org/blog/2009-04-13/easy-python-numpy-cuda-cublas/#comments</comments>
		<pubDate>Mon, 13 Apr 2009 21:03:17 +0000</pubDate>
		<dc:creator>derek</dc:creator>
				<category><![CDATA[open source]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://kered.org/blog/?p=97</guid>
		<description><![CDATA[CUDA is Nvidia&#8217;s C-like API for non-graphic number crunching on their 8xxx level and above video cards.  For certain operations, it is amazingly fast.  Unfortunately, it is painful in the extreme to use, especially when compared to Numpy, Python&#8217;s wonderful scientific computing package.
So, to marry the two, I wrote for myself some wrapper [...]]]></description>
			<content:encoded><![CDATA[<p>CUDA is Nvidia&#8217;s C-like API for non-graphic number crunching on their 8xxx level and above video cards.  For certain operations, it is amazingly fast.  Unfortunately, it is painful in the extreme to use, especially when compared to <a href="http://numpy.scipy.org/">Numpy</a>, <a href="http://www.python.org/">Python&#8217;s</a> wonderful scientific computing package.</p>
<p>So, to marry the two, I wrote for myself some wrapper code.  It&#8217;s pretty much only good for one thing: multiplying large matrices together really fast.  But it&#8217;s really good at it.  (and it&#8217;s really easy to use) For example:</p>
<p><code> import numpy<br />
from pycublas import CUBLASMatrix<br />
A = CUBLASMatrix( numpy.mat([[1,2,3],[4,5,6]],numpy.float32) )<br />
B = CUBLASMatrix( numpy.mat([[2,3],[4,5],[6,7]],numpy.float32) )<br />
C = A*B<br />
print C.np_mat()<br />
</code></p>
<p>All CUBLAS alloc and free calls are mapped to the CUBLASMatrix object&#8217;s life in Python, so you don&#8217;t have to worry about memory management.  (other than filling up the card, or course)</p>
<p>Here are some performance numbers: (includes memory transfer times)<br />
(4160&#215;4160)*(4160&#215;4160) = 43.0X faster than numpy<br />
(4096&#215;4096)*(4096&#215;4096) = 34.0X<br />
(3900&#215;3900)*(3900&#215;3900) = 47.3X<br />
(2048&#215;2048)*(2048&#215;2048) = 28.2X<br />
(1024&#215;1024)*(1024&#215;1024) = 58.8X<br />
(512&#215;512)*(512&#215;512)     = 24.1X<br />
(256&#215;256)*(256&#215;256)     = 6.3X<br />
(128&#215;128)*(128&#215;128)     = 1.1X<br />
CPU: Intel(R) Core(TM)2 Duo CPU E8400 @ 3.00GHz stepping 06<br />
GPU: nVidia Corporation GeForce 8800 GT (rev a2)</p>
<p>Note: This version only supports float32.<br />
Note: CUBLAS limits matrix dims to (65536&#215;65536).</p>
<p>Source code available here: <a href="http://kered.org/blog/wp-content/uploads/2009/04/pycublaspy1.txt">pycublas.py</a> (rename download to <code>pycublas.py</code> to use)</p>
]]></content:encoded>
			<wfw:commentRss>http://kered.org/blog/2009-04-13/easy-python-numpy-cuda-cublas/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Google&#039;s N-gram Corpus LDC2006T13</title>
		<link>http://kered.org/blog/2008-12-09/googles-n-gram-corpus-ldc2006t13/</link>
		<comments>http://kered.org/blog/2008-12-09/googles-n-gram-corpus-ldc2006t13/#comments</comments>
		<pubDate>Tue, 09 Dec 2008 23:48:55 +0000</pubDate>
		<dc:creator>derek</dc:creator>
				<category><![CDATA[open source]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://kered.org/blog/2008-12-09/googles-n-gram-corpus-ldc2006t13/</guid>
		<description><![CDATA[Google&#8217;s LDC2006T13 corpus is organized in an understandable but slightly annoying way; as a tar of split gzipped files.  To avoid having to untar it repeatedly, (in fact, at all, as it&#8217;s >100GB extracted), I wrote a small Python generator that let&#8217;s you iterate over them in their compressed state.  Usage is something [...]]]></description>
			<content:encoded><![CDATA[<p>Google&#8217;s <a href="http://www.ldc.upenn.edu/Catalog/CatalogEntry.jsp?catalogId=LDC2006T13">LDC2006T13</a> corpus is organized in an understandable but slightly annoying way; as a tar of split gzipped files.  To avoid having to untar it repeatedly, (in fact, at all, as it&#8217;s >100GB extracted), I wrote a small Python generator that let&#8217;s you iterate over them in their compressed state.  Usage is something like this:</p>
<blockquote><p><code>      corpus = LDC2006T13()<br />
for ngram, count in corpus.ngrams(3):<br />
&nbsp; print ngram, count<br />
</code></p></blockquote>
<p>Code is here: <a id="p91" href="/blog/wp-content/uploads/2008/12/ldc2006t13py.txt" title="LDC2006T13.py">LDC2006T13.py</a></p>
]]></content:encoded>
			<wfw:commentRss>http://kered.org/blog/2008-12-09/googles-n-gram-corpus-ldc2006t13/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing PyCUDA on Ubuntu 8.10</title>
		<link>http://kered.org/blog/2008-11-18/compiling-pycuda-on-ubuntu-810/</link>
		<comments>http://kered.org/blog/2008-11-18/compiling-pycuda-on-ubuntu-810/#comments</comments>
		<pubDate>Tue, 18 Nov 2008 20:28:47 +0000</pubDate>
		<dc:creator>derek</dc:creator>
				<category><![CDATA[open source]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://kered.org/blog/2008-11-18/compiling-pycuda-on-ubuntu-810/</guid>
		<description><![CDATA[I had to spend a bit of time working out the install procedure for PyCUDA on Ubuntu 8.10.  So I thought I&#8217;d share&#8230;

cd downloads/

Install the CUDA toolkit.  Ubuntu already comes with the 177.80 NVidia driver, so I didn&#8217;t install v177.73.

# install CUDA
wget http://developer.download.nvidia.com/compute/cuda/2_0/linux/driver/NVIDIA-Linux-x86_64-177.73-pkg2.run
wget http://developer.download.nvidia.com/compute/cuda/2_0/linux/toolkit/NVIDIA_CUDA_Toolkit_2.0_ubuntu7.10_x86_64.run
wget http://developer.download.nvidia.com/compute/cuda/2_0/linux/sdk/NVIDIA_CUDA_SDK_2.02.0807.1535_linux.run
chmod +x *.run
sudo ./NVIDIA_CUDA_Toolkit_2.0_ubuntu7.10_x86_64.run
# accepted default install location: /usr/local/cuda
su [...]]]></description>
			<content:encoded><![CDATA[<p>I had to spend a bit of time working out the install procedure for PyCUDA on Ubuntu 8.10.  So I thought I&#8217;d share&#8230;<br />
<code><br />
cd downloads/<br />
</code></p>
<p>Install the CUDA toolkit.  Ubuntu already comes with the 177.80 NVidia driver, so I didn&#8217;t install v177.73.<br />
<code><br />
# install CUDA<br />
wget http://developer.download.nvidia.com/compute/cuda/2_0/linux/driver/NVIDIA-Linux-x86_64-177.73-pkg2.run<br />
wget http://developer.download.nvidia.com/compute/cuda/2_0/linux/toolkit/NVIDIA_CUDA_Toolkit_2.0_ubuntu7.10_x86_64.run<br />
wget http://developer.download.nvidia.com/compute/cuda/2_0/linux/sdk/NVIDIA_CUDA_SDK_2.02.0807.1535_linux.run<br />
chmod +x *.run<br />
sudo ./NVIDIA_CUDA_Toolkit_2.0_ubuntu7.10_x86_64.run<br />
# accepted default install location: /usr/local/cuda<br />
su -<br />
echo "include /usr/local/cuda/lib" >> /etc/ld.so.conf.d/cuda.conf<br />
ldconfig<br />
cd /usr/bin/<br />
ln -s /usr/local/cuda/open64/bin/* .<br />
exit<br />
</code></p>
<p>Install Boost libs, v1.35.<br />
<code><br />
sudo apt-get install libboost-python1.35-dev<br />
</code></p>
<p>Install PyCUDA.<br />
<code><br />
wget http://pypi.python.org/packages/source/p/pycuda/pycuda-0.91.tar.gz#md5=339dac0641cc5da2f5c153d134592ed3<br />
tar -zxvf pycuda-0.91.tar.gz<br />
cd pycuda-0.91/<br />
./configure<br />
</code></p>
<p>Edit <code>siteconf.py</code> to look like this&#8230;<br />
<code><br />
BOOST_INC_DIR = ['/usr/include/boost/']<br />
BOOST_LIB_DIR = ['/usr/lib']<br />
BOOST_PYTHON_LIBNAME = ['boost_python-mt-py25']<br />
CUDA_ROOT = '/usr/local/cuda/'<br />
CUDADRV_LIB_DIR = []<br />
CUDADRV_LIBNAME = ['cuda']<br />
CXXFLAGS = []<br />
LDFLAGS = []<br />
</code></p>
<p>Then take her home&#8230;<br />
<code><br />
python setup.py build<br />
sudo make install<br />
</code></p>
<p>Now to test:<br />
<code><br />
#export C_INCLUDE_PATH=/usr/local/cuda/include/<br />
#export CPLUS_INCLUDE_PATH=/usr/local/cuda/include/<br />
export PATH=$PATH:/usr/local/cuda/bin/<br />
cd test<br />
python test_driver.py<br />
</code></p>
<p>The tests run successfully for me, sans <code>test_mempool (__main__.TestCuda)</code>.  I&#8217;ll update this as I find out more.</p>
]]></content:encoded>
			<wfw:commentRss>http://kered.org/blog/2008-11-18/compiling-pycuda-on-ubuntu-810/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ARPA Language Model File Format</title>
		<link>http://kered.org/blog/2008-08-12/arpa-language-model-file-format/</link>
		<comments>http://kered.org/blog/2008-08-12/arpa-language-model-file-format/#comments</comments>
		<pubDate>Tue, 12 Aug 2008 19:50:07 +0000</pubDate>
		<dc:creator>derek</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://kered.org/blog/2008-08-12/arpa-language-model-file-format/</guid>
		<description><![CDATA[The format of a ARPA language model file, as far as I can tell, is not documented outside of the CMU SLM toolkit source code.  I&#8217;m regurgitating it here in the hopes that future Google searches on this topic are more fruitful than mine were.   
/* This is the format introduced and [...]]]></description>
			<content:encoded><![CDATA[<p>The format of a ARPA language model file, as far as I can tell, is not documented outside of the CMU SLM toolkit source code.  I&#8217;m regurgitating it here in the hopes that future Google searches on this topic are more fruitful than mine were.  <img src='http://kered.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<blockquote><pre>/* This is the format introduced and first used by Doug Paul.
   Optionally use a given symbol for the UNK word (id==0).
*/
/*
Format of the .arpabo file:
------------------------------
<header info - ignored by programs>
\data\
ngram 1=4989
ngram 2=835668
ngram 3=12345678

\1-grams:
...
-0.9792 ABC   -2.2031
...
log10_uniprob(ZWEIG)   ZWEIG   log10_alpha(ZWEIG)

\2-grams:
...
-0.8328 ABC DEFG -3.1234
...
log10_bo_biprob(WAS | ZWEIG)  ZWEIG  WAS   log10_bialpha(ZWEIG,WAS)

\3-grams:
...
-0.234 ABCD EFGHI JKL
...

\end\
*/
</pre>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://kered.org/blog/2008-08-12/arpa-language-model-file-format/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SVN/Trac Integration</title>
		<link>http://kered.org/blog/2008-06-27/svntrac-integration/</link>
		<comments>http://kered.org/blog/2008-06-27/svntrac-integration/#comments</comments>
		<pubDate>Fri, 27 Jun 2008 20:27:05 +0000</pubDate>
		<dc:creator>derek</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://kered.org/blog/2008-06-27/svntrac-integration/</guid>
		<description><![CDATA[A long time ago I wrote an article titled CVS/Bugzilla Integration.  Here is an updated version for subversion and trac.
Note that it doesn&#8217;t require access the trac python libs or database; it just uses HTTP.  But it does require BeautifulSoup. Install it by adding it to your hooks post-commit script.  (it takes [...]]]></description>
			<content:encoded><![CDATA[<p>A long time ago I wrote an article titled <a href="http://kered.org/blog/2004-04-09/6/">CVS/Bugzilla Integration</a>.  Here is an updated version for subversion and trac.</p>
<p>Note that it doesn&#8217;t require access the trac python libs or database; it just uses HTTP.  But it does require <a href="http://www.crummy.com/software/BeautifulSoup/">BeautifulSoup</a>. Install it by adding it to your hooks post-commit script.  (it takes the normal params of REPOS and REV).</p>
<p><span id="more-84"></span></p>
<blockquote><pre>#!/usr/bin/env python

import os, re, sys, urllib, urllib2

from BeautifulSoup import BeautifulSoup

TRAC_URL = 'http://my.trac.url'
TRAC_TICKET_REL_URL = '/xxx/ticket/'
TRAC_LOGIN_REL_URL = '/xxx/login/'
TRAC_USER = 'user'
TRAC_PASS = 'pass'
TRAC_REALM = 'myRealm'
#SVNLOOK = '/usr/bin/svnlook'
SVNLOOK = '/usr/local/bin/svnlook'

TRAC_TICKET_URL = TRAC_URL+TRAC_TICKET_REL_URL
TRAC_LOGIN_URL = TRAC_URL+TRAC_LOGIN_REL_URL

def get_commit_info(repos, rev):
    c = os.popen( SVNLOOK+' info "%s" -r "%s"' % (repos, rev) )
    user = c.readline().strip()
    date = c.readline().strip()
    ignore = c.readline().strip()
    msg = c.read()
    c.close()
    return user, date, msg

def get_trac_tickets(msg):
    p = re.compile(r'trac:\d+')
    tickets = p.findall(msg)
    return [ t[5:] for t in tickets ]

def post_to_trac( ticket, msg ):
    auth = urllib2.HTTPDigestAuthHandler()
    auth.add_password(TRAC_REALM, TRAC_URL, TRAC_USER, TRAC_PASS)
    opener = urllib2.build_opener(auth, urllib2.HTTPCookieProcessor())
    req = urllib2.Request(TRAC_LOGIN_URL)
    req.add_header("Referer", TRAC_TICKET_URL+ticket)
    try:
        res = opener.open(req)
        html = res.read()
        soup = BeautifulSoup(html)
        form = soup.find('form', action=TRAC_TICKET_REL_URL+ticket+'#preview')
        data = {}
        for i in form.findAll('input'):
            try:
                if i['type']=='hidden' or i['type']=='text':
                    data[ i['name'] ] = i['value']
                if i['type']=='checkbox' or i['type']=='radio':
                    if i.get('checked'):
                        data[ i['name'] ] = i['value']
            except: pass
        for s in form.findAll('select'):
            for o in s.findAll('option'):
                if o.get('selected'):
                    data[ s['name'] ] = o.get('value',o.string)
        data['comment'] = msg
        #data['preview'] = 'Preview'
        #print '\n'.join([ str(x) for x in data.iteritems() ] )
        req = urllib2.Request(TRAC_TICKET_URL+ticket, urllib.urlencode(data))
        req.add_header("Referer", TRAC_TICKET_URL+ticket)
        res = opener.open(req)
        html = res.read()
        #print html

    except IOError, e:
        pass
#      if hasattr(e, 'code'):
#        if e.code != 401:
#            print 'We got another error'
#            print e.code
#        else:
#            print e.headers

def main(*args):

    if len(args)!=3:
        print 'usage: python commit-trac.py "repos" "rev"'
        return 1

    repos = args[1]
    rev = args[2]
    user, date, msg = get_commit_info(repos, rev)
    msg = 'svn commit to %s -r%s (%s):\n%s' % (repos, rev, user, msg)
    print msg

    for ticket in get_trac_tickets(msg):
        post_to_trac( ticket, msg )

    return 0 # exit errorlessly

if __name__ == '__main__':
    sys.exit(main(*sys.argv))
</pre>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://kered.org/blog/2008-06-27/svntrac-integration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
