Tuesday, December 02, 2008

Today, the little choncho turns 3! It really is unbelievable to me that she could be this old.  We woke her up this morning, and gave her one of her presents, some butterfly wings.  She really liked them.

I’ll take a rare moment to brag about her publicly, not because I think she’s better than your kid, or because I’m an awesome parent (I’m not), but because I love her and I’m so proud of her.  She is so awesome and sweet and polite (most of the time).  Even when she’s upset, she’ll say “thanks” when you hand her something.  She’s beginning to read, can do some simple math, and loves to draw and paint (the latter can become quite messy).  She builds the greatest things out of blocks and legos.  We went to Red Robin on Sunday, and I asked her to circle the items she wanted from the kids menu.  She circled mac ‘n cheese and oranges.

Happy Birthday, Choncho!

posted on Tuesday, December 02, 2008 11:45:18 AM (Pacific Standard Time, UTC-08:00)  #    Comments [0]
 Thursday, November 20, 2008

My brother-in-law posted a note on Facebook that was basically one of those silly things you do and perpetuate across the internet.  I usually don’t take part in such things, but this one seemed interesting, and I’ve been thinking about ways to jumpstart my blogging again now that the embargo on all the cool stuff is lifted.  So, I thought I would do it.  Here are the rules:

  • Grab the book nearest you. Right now.
  • Turn to page 56.
  • Find the fifth sentence.
  • Post that sentence along with these instructions in a note to your wall. (this was on Facebook, so it is referring to that wall)
  • Don't dig for your favorite book, the coolest, the most intellectual. Use the CLOSEST.

So, it took me a while to determine which book was the “closest”, as my position is roughly normal to the bookshelf in my office.  I finally decided to be honest and pick the one that was really closest, but I will share another that was very close, as it is a good segue into future blogs.

The first (and official) one:

Semiconductor materials at 0 K have basically the same structure as insulators – a filled valence band separated from an empty conduction band by a band gap containing no allowed energy states (Fig. 3-4).

Solid State Electronic Devices, Ben G. Streetman

The second, and more relevant/interesting one:

The shim’s algorithm for picking a version in the COM interoperability scenario is much more straightforward – the latest version installed on the machine is always used.

Customizing the Microsoft .NET Framework Common Language Runtime, Steven Pratschner

What is amazing about this second one is that this is directly related to one of the features I’ve been working on for CLR v4 (and yes, that is actually the 5th sentence on page 56).  Namely, this feature is known as “in-process side by side” (or in-proc SxS for short), and was announced publicly at PDC last month.  This feature allows you to have more than version of the CLR loaded and running in a single process.

This feature is primarily a compatibility feature, targeted precisely at the behavior noted in the quote above.  When we use the latest version, we can break existing COM objects.  Not only because of breaking changes we make (of which the number is fairly small), but because of other, more subtle behavior dependencies.

Previously, loading a CLR version into the process locked the process to that CLR version.  Any other policy than “pick the latest” results in a load order dependency problem that can result in “for sure” breaks because COM components targeting newer runtimes cannot run on old runtimes.  So, clearly, that was the best choice of policies.

Now that we support multiple runtimes in the process (v2 and above), we can make a smarter, more compatible choice about runtime activation.  The precise policies are still being worked through, so I’ll avoid stating them explicitly, but you can imagine us being able to make a much better choice about what runtime to activate to run a given managed COM component.

I’ll be posting more about this feature and it’s implications soon.  Feel free to seed my future posts with questions in the comments.  Hopefully, this is the jumpstart I needed.  As for the “game” above, feel free to do it, or ignore it.  It won’t result in any difference to your luck, financial situation, or anything else.

posted on Thursday, November 20, 2008 5:25:12 PM (Pacific Standard Time, UTC-08:00)  #    Comments [1]
 Tuesday, October 21, 2008

I just leveled up my uncle character!  Luke Andrew Miller was born Sunday night (Oct. 19th) at 9:39 PM.  6 lbs. 13 ounces, 19 inches.

I had originally planned my trip to visit my brother Andrew to be well before Luke was due, but he was so excited to see me that he had to come early :).  It was so great that I was able to help Andrew and Sara out while I was there.  I got alot of play time in with my nephew Landon, who I haven’t gotten to see hardly at all since we moved to Seattle and they moved to Midland.  While Andrew and Sara went to the hospital, I watched Landon and we had a great time.

Hanging out with Andrew was also a blast.  We play Halo together all the time, but it’s just alot more fun to hang out in person.  We didn’t have much of an agenda, just hanging out and inventing weird games to play.  He also introduced me to some new kid’s shows that I think Jenna will enjoy.  WordWorld is awesome.  I got Jenna the cat, which you can take apart into the the letters C, A, and T.  She LOVES it.

I also got to eat a bunch of food that isn’t available where I live:

  • Chick-fil-a – I had chicken minis for breakfast when I arrived, and we ate there again later and I had 2 sandwiched, and some nuggets.  Delicious.
  • Blue Bell Ice Cream – I really don’t know how they make it so good.  It is far and above better than any other ice cream available in Seattle.
  • Sonic – I usually opt for a flurry, but I had already eaten a ton of Blue Bell, so I got a vanilla coke (a coke with vanilla added, not the Vanilla Coke that coke makes).
  • Mexican Food – Sure, there are a bunch of Mexican food places here in the Seattle area, but they pale in comparison to what’s available in Texas (especially Midland).  I had chicken fajita soft tacos and sopaipillas from Rosa’s.

There simply weren’t enough meals to hit everything I wanted.  I missed out on Whataburger and On the Border (more Mexican Food).

You can check out my Flickr set, which is a ton of pictures of Landon, and a few of Luke at 5:00am when I got to meet him before flying out.

posted on Tuesday, October 21, 2008 10:45:19 AM (Pacific Standard Time, UTC-08:00)  #    Comments [2]
 Friday, September 26, 2008

Richard Lander, one of our PMs, just started a series of posts on deployment.  Specifically, he’s taking the approach of thinking about your v2 strategy while you are still working on v1 of your product.  If you’re already on v3 of your product, don’t worry.  There will still be some useful, interesting information for you. The first post just lays the groundwork for the discussion, so stay tuned for the rest.

posted on Friday, September 26, 2008 9:54:59 AM (Pacific Standard Time, UTC-08:00)  #    Comments [0]
 Friday, July 25, 2008

I didn't get up an anniversary post yesterday because I was busy DOING stuff for my anniversary this year.  Unbeknownst to Becky, I arranged to take the day off. I sneakily got a late-morning massage appointment for her, and lined up a babysitter (thanks, Molly) so we could go see a movie in the afternoon.  Everything went off without a hitch.

We went to see the latest Indiana Jones movie, which we enjoyed very much despite the somewhat less than explanatory ending. We hadn't been to the theater to see a movie since Pirates II.  But, we both agreed that we aren't missing much except time alone and seeing the latest movies.

posted on Friday, July 25, 2008 1:04:47 PM (Pacific Standard Time, UTC-08:00)  #    Comments [1]
 Friday, June 20, 2008

Some of my posts that I get the most recurring email/inquiries on are my various posts about the STDF (Standard Test Datalog Format) parser that I originally created as an experiment back in 2005.  After some help from a former collegue, I am pleased to announce that this is finally available on CodePlex as LinqToStdf!

It is a managed library for processing STDF files, and gives you a model to explore the data via Linq queries.  This means, you can leverage the wide variety of managed languages (C#, VB, F#, JScript, IronPython, IronRuby, Managed C++, Boo, etc.) to process the data in STDF files.  It also works in Silverlight!  It has built-in support for the V4 spec, but it's highly extensible and should be able to parse any version of the file format as well as custom records.  It can be configured to be highly strict and throw on format errors, or be robust in the face of issues that normal STDF processors would choke on to the point of being able to detect and repair corruption on the fly.

If that interests you, I'd love for you to drop by and take a deeper look at it and get involved in its ongoing development.  I've already got at least one person interested enough to contribute and ensure its success as a community project.  There is currently a "beta" release available, and hopefully we'll whip it into shape enough to call it v1.0 soon.

My hope is that this can be an adoption driver for .NET in the semiconductor industry and that through this project I can be an ambassador for the CLR in that area.

posted on Friday, June 20, 2008 1:05:13 PM (Pacific Standard Time, UTC-08:00)  #    Comments [2]
 Tuesday, June 10, 2008

I've been playing alot with beta 2 of Silverlight 2, and I've been totally amazed at the scenarios it enables.  Working hard down inside the CLR engine, we're sometimes insulated from some of the innovation going on higher in the stack and it blows us away when we do get a chance to see it.

One of the very cool things in Silverlight is "Deep Zoom", which came from the SeaDragon project from Microsoft Research.  I decided to try it out myself on a very large panorama that I made a long time ago in New Orleans.  Unfortunately, the current toolset seems to trip over the large file size (20516x15291).  I'm trying to find out the real story behind the limitation.  All I know right now is that smaller files work.

So, I decided to try to slice it up into smaller, manageable chunks and just butt them against one another to simulate one large file.  The problem was that I couldn't find a tool to do this that didn't also trip up over the size of the file.  So, I wrote my own.  There are likely better ways to do this, this was just a quick and dirty attempt to make something that didn't totally crawl to a halt due to page faulting (or outright throw OutOfMemoryException).

The code below is what I came up with.  I use System.Drawing.Bitmap, lock the portions of the image I need, and do the data copying myself.  I ended up with this solution because GDI+ (DrawImage) seems to like to make alot of buffers (big ones in this case), and I couldn't fall back on good ol' bitblt because I couldn't get the right kind of data structures without more copying of the data.  This runs plenty fast and only takes up marginally more memory than it takes to represent the original and the size of one of the destination tiles.

Unfortunately, The MultiScaleImage does some weirdness with image that are butted up against each other, and you get as much as a whole pixel of "space" between them, depending on your zoom level. I'm still looking into other possible workarounds. So, it's wasn't ultimately useful, but I thought the code was interesting enough, and probably has academic usefulness.  So, enough talk, here's the code:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Drawing;
   4:  using System.Drawing.Imaging;
   5:  using System.IO;
   6:  using System.Linq;
   7:  using System.Runtime.InteropServices;
   8:   
   9:  namespace ImageSlicer {
  10:      static class Extensions {
  11:          public static IEnumerable<int> Times(this int number) {
  12:              for (var i = 0; i < number; i++) yield return i;
  13:          }
  14:      }
  15:   
  16:      class Program {
  17:          [DllImport("msvcrt.dll", SetLastError = false)]
  18:          static unsafe extern byte* memcpy(byte* dest, byte* src, int count);
  19:   
  20:          static void Main(string[] args) {
  21:              var sourcePath = args.FirstOrDefault();
  22:              if (String.IsNullOrEmpty(sourcePath)) {
  23:                  Console.WriteLine("No source image path provided");
  24:                  ShowUsage();
  25:                  return;
  26:              }
  27:              if (!File.Exists(sourcePath)) {
  28:                  Console.WriteLine("Source image path doesn't exist");
  29:                  return;
  30:              }
  31:              var gridSizeStr = args.Skip(1).FirstOrDefault();
  32:              int gridSize = 4;
  33:              if (gridSizeStr != null && !int.TryParse(gridSizeStr, out gridSize)) {
  34:                  Console.WriteLine("Could not convert {0} to a valid grid size",
  35:                      gridSizeStr);
  36:                  return;
  37:              }
  38:              if (gridSize < 2) {
  39:                  Console.WriteLine("The grid size must be greater than 1.");
  40:                  return;
  41:              }
  42:              try {
  43:                  Console.WriteLine("Slicing {0} into a {1}x{1} grid.",
  44:                      Path.GetFileName(sourcePath), gridSize);
  45:                  Console.WriteLine("Loading...");
  46:                  using (var sourceBitmap = new Bitmap(sourcePath)) {
  47:                      Console.WriteLine("Source Image: {0}x{1}",
  48:                          sourceBitmap.Width, sourceBitmap.Height);
  49:                      var sliceWidth = sourceBitmap.Width / gridSize;
  50:                      var sliceHeight = sourceBitmap.Height / gridSize;
  51:                      Console.WriteLine("Each slice: {0}x{1}", sliceWidth, sliceHeight);
  52:                      int tile = 0;
  53:                      foreach (var row in gridSize.Times()) {
  54:                          foreach (var column in gridSize.Times()) {
  55:                              Console.WriteLine("Creating {0} of {1} ({2},{3})",
  56:                                  ++tile, gridSize * gridSize, column, row);
  57:                              using (var destBitmap = new Bitmap(sliceWidth, sliceHeight)) {
  58:                                  var sourceData = sourceBitmap.LockBits(
  59:                                      new Rectangle(column * sliceWidth,
  60:                                          row * sliceHeight, sliceWidth,
  61:                                          sliceHeight),
  62:                                      ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
  63:                                  var destData = destBitmap.LockBits(
  64:                                      new Rectangle(0, 0, sliceWidth, sliceHeight),
  65:                                      ImageLockMode.WriteOnly, sourceData.PixelFormat);
  66:                                  unsafe {
  67:                                      byte* pSrc = (byte*)sourceData.Scan0.ToPointer();
  68:                                      byte* pDest = (byte*)destData.Scan0.ToPointer();
  69:                                      foreach (var line in sliceHeight.Times()) {
  70:                                          memcpy(pDest, pSrc, sliceWidth * 3);
  71:                                          pSrc += sourceData.Stride;
  72:                                          pDest += destData.Stride;
  73:                                      }
  74:                                  }
  75:                                  sourceBitmap.UnlockBits(sourceData);
  76:                                  destBitmap.UnlockBits(destData);
  77:                                  destBitmap.Save(String.Format("{0}_{1}_{2}.png",
  78:                                      Path.GetFileNameWithoutExtension(sourcePath),
  79:                                      column, row), ImageFormat.Png);
  80:                              }
  81:                          }
  82:                      }
  83:                  }
  84:              }
  85:              catch (Exception ex) {
  86:                  Console.WriteLine("Error processing image.");
  87:                  Console.WriteLine(ex.ToString());
  88:              }
  89:          }
  90:   
  91:          private static void ShowUsage() {
  92:              Console.WriteLine("Usage:");
  93:              Console.WriteLine("ImageSlicer.exe sourceImage [gridSize]");
  94:          }
  95:      }
  96:  }
posted on Tuesday, June 10, 2008 10:01:35 PM (Pacific Standard Time, UTC-08:00)  #    Comments [5]
 Friday, May 09, 2008

Why not come work on the Common Language Runtime team at Microsoft?  My team is a team of SDETs (Software Development Engineer in Test) that works in the really low levels of the CLR.  We cover areas like assembly loading/fusion, AppDomains, the shim (mscoree), and interop.

As an SDET, you are in charge of all aspects of quality for the areas you own. This means you get to be involved in the design process and be literally the first person developing code using new features coming out of the team.  I've found my last year and a half here to be extremely satisfying.

This is a pretty exciting time to join the team as we're working on some long-lead items for the next version of the CLR and we're also busy shipping Silverlight 2 and .NET Framework 3.5 SP1.

You'll need strong coding, problem-solving, and communication skills.  Some background on the CLR and managed code is a plus, but not required.  If you think you've got what it takes to join the team, check out the job details and submit your resume.  I'm happy to answer questions about the team and the jobs within reason, so feel free to ping me at marklio at [you-know-where].com.

There are several openings in other areas of the team as well.  Feel free to search the other CLR jobs and find the one that's right for you.

posted on Friday, May 09, 2008 10:40:09 AM (Pacific Standard Time, UTC-08:00)  #    Comments [0]