John, Dave, and I were trying to run a Visual Studio 2005 OpenMP code on cluster nodes. We ran into an extra wrinkle with the isolated assembly for Visual Studio’s OpenMP. In addition, a curiously low-tech bug in Visual Studio kept us from discovering we had the correct solution.
Typical deployment of isolated assemblies on a cluster node
We have already covered the typical story for isolated assemblies. If an application uses a dll which was compiled as an isolated assembly, then the application has to contain a manifest which specifies those assemblies. Visual Studio automatically embeds that manifest in the application. When you deploy that application to a new machine, Microsoft recommends that you use an installer to install that assembly as a shared assembly, meaning that the installer places the assembly in the WinSxS folder in the Windows folder, which functions like a GAC. Visual Studio even includes a vcredist.exe program to install all of the release versions of Visual Studio isolated assemblies into the WinSxS folder.
Because we are running on cluster nodes, we want to know how to deploy those isolated assemblies, instead, as private assemblies. This is usually a simple matter. You find directory for the isolated assembly, such as Microsoft.VC80.DebugCRT, in C:\Program Files\Visual Studio 8\VC\redist\Debug_NonRedist\x86. Copy the whole directory to the same directory as your executable on the cluster node, and everything should work.
By the way, Dave installed the redistributable, release version, isolated assemblies on one of the clusters. We have to figure out whether we will install all Visual Studio assemblies on the clusters for the users. The problem will still exist for other isolated assemblies, although we don’t, at this point, know of any coming from companies other than Microsoft or products other than Visual Studio.
How OpenMP requires another step to deploy
When you try the above technique for OpenMP, the executable still fails to find the assembly on the cluster node. When Visual Studio compiles your OpenMP program, it embeds a manifest file that refers to version 8.0.50608.0 of the OpenMP assembly, but the actual assembly is version is 8.0.50727.42. Why would this work on your machine? It works because your computer has a machine-level policy, sitting in %windows%\WinSxS\Policies, which states that, if any application asks for version 8.0.50608.0, it’s okay to give them 8.0.50727.42.
The version mismatch between the distributed assembly and the assembly required by the compiler is a known problem. It happens because different parts of Visual Studio are frozen at differnt times before delivery. What we have to do to make this run on the cluster is to deploy that same policy as an application configuration file.
Application configuration files for native application files are very similar to those for managed files. If your program is myprog.exe, you make a text file, with UTF-8 encoding (with or without a byte-order mark), called myprog.exe.config. In it, you redirect the program’s binding to the newer version of the debug OpenMP assembly. Note that, when you identify the DebugOpenMP assembly, you leave out the version attribute because you will specify it in the bindingRedirect node.
<span style="color:#3333ff;"><configuration>
<windows>
<assemblybinding xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyidentity name="myprog.exe" processorarchitecture="x86" version="1.0.0.1" type="win32">
<dependentassembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.DebugOpenMP"
processorArchitecture="x86"
publicKeyToken="1fc8b3b9a1e18e3b"/>
<bindingredirect oldversion="8.0.50608.0" newversion="8.0.50727.42">
</dependentassembly>
</assemblybinding>
</windows>
</configuration>
</span>
If we had deployed the OpenMP assembly to WinSxS, so that it was a shared assembly, I think that there would have been a machine-level policy to take care of the version mismatch. As is, we had to make this file for ourselves and deploy it in the same directory as myprog.exe.
How a little bug made this hard to figure out
Yesterday morning, we had figured out that there was a version mismatch and that an application configuration file was necessary. We had copied the debug OpenMP assembly directory into the same directory as our application, but nothing worked. After five hours, we noticed that the debug OpenMP assembly directory was called Micrsoroft.VC80.DebugOpenMP. If you look in your Studio 2005 VC\Debug_NonRedist\x86 directory, you’ll find that the directory name is wrong.
Drew Dolgert
1 comment:
Hehe...! Just noticed this myself... Funny that no service-pack (at least not one that has been installed on my system) has fixed this...
It's now late 2009, and still the files reside in the Micorosft directory... *sigh*.
Post a Comment