<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://www.sharcnet.ca/help/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tyson</id>
		<title>Documentation - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://www.sharcnet.ca/help/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tyson"/>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php/Special:Contributions/Tyson"/>
		<updated>2026-05-23T23:10:15Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.25.2</generator>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=16234</id>
		<title>NIX</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=16234"/>
				<updated>2018-01-13T20:16:47Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Add directions to entirely reset nix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=NIX&lt;br /&gt;
|package_description=User Level Purely Functional Package Manager&lt;br /&gt;
|package_idnumber=171&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
Nix is a package manager system that allows users to manage their own software environment.  This environment is persistent and is shared across all clusters.&lt;br /&gt;
&lt;br /&gt;
* Users can build, install, upgrade, downgrade, and remove packages from their environment without root privileges and without affecting other users.&lt;br /&gt;
* Operations either succeed and create a new environment or fail leaving the previous environment in place (operations are atomic).&lt;br /&gt;
* Previous environments can be switched back to at any point.&lt;br /&gt;
* Users can add their own packages and share them with other users.&lt;br /&gt;
&lt;br /&gt;
The default Nix package set includes a huge selection (over 10,000) of recent versions of many packages.&lt;br /&gt;
== Enabling and disabling the Nix environment ==&lt;br /&gt;
&lt;br /&gt;
The user's current Nix environment is enabled by loading the nix module. This creates some ''.nix*'' files and sets some environment variables.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is disabled by unloading the nix module. This unsets the environment variables but leaves the ''.nix*'' files alone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module unload nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&lt;br /&gt;
module load nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Completely reseting the Nix environment ==&lt;br /&gt;
&lt;br /&gt;
Most operations can be undone with the &amp;lt;code&amp;gt;--rollback&amp;lt;/code&amp;gt; option (i.e.,  &amp;lt;code&amp;gt;nix-env --rollback&amp;lt;/code&amp;gt; or  &amp;lt;code&amp;gt;nix-channel --rollback&amp;lt;/code&amp;gt;). Sometimes it is useful to entirely reset nix though. This is done by unloading the module, erasing all user related nix files, and then reloading the module file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module unload nix&lt;br /&gt;
rm -fr ~/.nix-profile ~/.nix-defexpr ~/.nix-channels ~/.config/nixpkgs&lt;br /&gt;
rm -fr /nix/var/nix/profiles/per-user/$USER /nix/var/nix/gcroots/per-user/$USER&lt;br /&gt;
module load nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Installing and remove packages =&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; command is used to setup your Nix environment.&lt;br /&gt;
== What do I have installed and what can I install ==&lt;br /&gt;
&lt;br /&gt;
Lets first see what we currently have installed.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Now let's see what is available. We request the attribute paths (unambiguous way of specifying a package) and the descriptions too (cursor to the right to see them). This takes a bit of time as it visits a lot of small files. Especially over NFS it can be a good idea to pipe it to a file and then grep that in the future.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query --available --attr-path --description&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Installing packages ==&lt;br /&gt;
&lt;br /&gt;
Let's say that we need a newer version of git than provided by default on our OS (e.g., the CentOS 6 one has issues with fetching over https). First lets check what our OS comes with.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git --version&lt;br /&gt;
which git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let's tell Nix to install its version in our environment.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr nixpkgs.git&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let's checkout what we have now (it may be necessary to tell bash to to forget remembered executable locations with &amp;lt;code&amp;gt;hash -r&amp;lt;/code&amp;gt; so it notices the new one).&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git --version&lt;br /&gt;
which git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Removing packages ==&lt;br /&gt;
&lt;br /&gt;
For completeness, lets add in the other usual version-control suspects.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr nixpkgs.subversion nixpkgs.mercurial&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Actually, we probably don't really want subversion any more. Let's remove that.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --uninstall subversion&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Environments =&lt;br /&gt;
&lt;br /&gt;
Nix keeps referring to user environments. Each time we install or remove packages we create a new environment based off of the previous environment.&lt;br /&gt;
== Switching between previous environments ==&lt;br /&gt;
&lt;br /&gt;
This means the previous environments still exist and we can switch back to them at any point. Let's say we changed our mind and want subversion back. It's trivial to restore the previous environment.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --rollback&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Of course we may want to do more than just move to the previous environment. We can get a list of all our environments so far and then jump directly to whatever one we want. Let's undo the rollback.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --list-generations&lt;br /&gt;
nix-env --switch-generation 4&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Operations are atomic ==&lt;br /&gt;
&lt;br /&gt;
Due to the atomic property of Nix environments, we can't be left halfway through installing/updating packages. They either succeed and create us a new environment or leave us with the previous one intact.&lt;br /&gt;
&lt;br /&gt;
Let's go back to the start when we just had Nix itself and install the one true GNU distributed version control system tla. Don't let it complete though. Hit it with &amp;lt;code&amp;gt;CTRL+c&amp;lt;/code&amp;gt; partway through.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --switch-generation 1&lt;br /&gt;
nix-env --install --attr nixpkgs.tla&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+c&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Nothing bad happens. The operation didn't complete so it has no effect on the environment whatsoever.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query&lt;br /&gt;
nix-env --list-generations&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Nix only does things once ==&lt;br /&gt;
&lt;br /&gt;
The install and remove commands take the current environment and create a new environment with the changes. This works regardless of which environment we are currently in. Let's create a new environment from our original environment by just adding git and mercurial.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --list-generations&lt;br /&gt;
nix-env --install nixpkgs.git nixpkgs.mercurial&lt;br /&gt;
nix-env --list-generations&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Notice how much much faster it was to install git and mercurial the second time? That is because the software already existed in the local Nix store from the previous installs so Nix just reused it.&lt;br /&gt;
== Garbage collection ==&lt;br /&gt;
&lt;br /&gt;
Nix periodically goes through and removes any software not accessible from any existing environments. This means we have to explicitly delete environments we don't want anymore so Nix is able to reclaim the space. We can delete specific environments or any sufficiently old.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --delete-generations 30d&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Using channels to obtain Nix expressions =&lt;br /&gt;
&lt;br /&gt;
Nix packages are Nix expressions that specify how to build something. The default source for of these expression for &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; is ''~/.nix-defexp'' and ''~/.nix-defexp/channels''. Nix channels provide a way to populate this later directory with existing expressions from repositories on the internet.&lt;br /&gt;
== Subscribing to a channel ==&lt;br /&gt;
&lt;br /&gt;
By default we are subscribed to the SHARCNET version of the latest NixOS release under the name nixpkg. Let us add the older NixOS 15.09 release too under the name nixpkgs_old and then download the latest versions of all NixOS 15.09 the expressions.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-channel --list&lt;br /&gt;
nix-channel --add file:///nix/channels/sharcnet-15.09 nixpkgs_old&lt;br /&gt;
nix-channel --list&lt;br /&gt;
nix-channel --update nixpkgs_old&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Installing packages from a channel ==&lt;br /&gt;
&lt;br /&gt;
Now searching our available packages we see that we can install software using either the nixpkgs or nixpkgs_old expressions.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query --available --attr-path --description git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let's replace our git built and installed from the unstable (nixpkgs) expression with one built and installed from the stable expression (note that git is the default version of git which is gitMinimal).&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr nixpkgs_old.git&lt;br /&gt;
nix-env --query&lt;br /&gt;
git --version&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== What about dependency conflicts ==&lt;br /&gt;
&lt;br /&gt;
There are no issues with having a mix of packages installed from different sources even if they have conflicting dependencies. Nix puts each package in a separate directory under ''/nix/store'' versioned by the hash of the its build instructions. Binaries are linked with rpaths to ensure they always find the versions they need.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ldd $(readlink ($which git))&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Switching between environments continue to work as before.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --rollback&lt;br /&gt;
git --version&lt;br /&gt;
nix-env --list-generations&lt;br /&gt;
nix-env --switch-generation 5&lt;br /&gt;
git --version&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Switching between previous updates ==&lt;br /&gt;
&lt;br /&gt;
The channel updates (updating the list of expressions we can build and install from) are also atomic and versioned. This ensures we never find ourselves stuck due to accidentally updating to something broken.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-channel --rollback&lt;br /&gt;
nix-env --query --available --attr-path git&lt;br /&gt;
nix-channel --rollback 2&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Development with Nix (e.g., Python, R, etc.) =&lt;br /&gt;
&lt;br /&gt;
Several languages have their own repository of packages and associated infrastructure (e.g., PyPI and pip). Nix builds on these to automatically handle the external dependencies (e.g., C libraries) and makes it easy to work simultaneously with different projects requiring different versions of internal packages.&lt;br /&gt;
== Wrapper scripts for setting paths ==&lt;br /&gt;
&lt;br /&gt;
Nix has expressions for many of these that generate wrapper scripts that set path environment variables to bring a specific set of the internal packages into scope and then run the approriate program.&lt;br /&gt;
&lt;br /&gt;
The following Nix expression defines top-level myPython, myR, and myHaskell attributes that use the appropriate package-specific expressions to create wrappers for a selection of internal packages (for details about the Nix langauge see the [https://nixos.org/nix/manual/#ch-expression-language Nix Expression Language].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import &amp;amp;lt;nixpkgs&amp;amp;gt; { };&lt;br /&gt;
&lt;br /&gt;
rec {&lt;br /&gt;
  myPython = python3.buildEnv.override rec {&lt;br /&gt;
    extraLibs = with python3Packages; [ numpy scipy ];&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  myR = rWrapper.override rec {&lt;br /&gt;
    packages = with rPackages; [ rgeos rgdal ];&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  myHaskell = haskellPackages.ghcWithPackages (ghcpkgs:&lt;br /&gt;
    with ghcpkgs; [ pipes lens cabal-install ]&lt;br /&gt;
  );&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Saving it as ''~/.nix-defexpr/mypkgs.nix'' makes these available for installation with &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr mypkgs.myPython&lt;br /&gt;
cat $(which python3)&lt;br /&gt;
python3&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;import scipy&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+d&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
== Development environments ==&lt;br /&gt;
&lt;br /&gt;
A Nix expression evaluates to a specification for setting up a (build) environment and then doing a build in it. Frequently we want to do something very similar: setup a (development) environment and then do development in it.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-shell&amp;lt;/code&amp;gt; command bridges the gap between these two. It uses Nix to sets up a non-rooted (build) environment with the dependencies we specify and then laucnhes a (development) shell in it instead of a build process.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;mkdir devel&lt;br /&gt;
cd devel&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Say we need Clang and Python with the NumPy and SciPy packages. Instead of installing these into our global environment we can create a Nix expression that specifies these as build (development) inputs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import &amp;amp;lt;nixpkgs&amp;amp;gt; { };&lt;br /&gt;
&lt;br /&gt;
stdenv.mkDerivation {&lt;br /&gt;
  name = &amp;amp;quot;my-env&amp;amp;quot;;&lt;br /&gt;
  buildInputs = [&lt;br /&gt;
    ( python3.buildEnv.override rec {&lt;br /&gt;
        extraLibs = with python3Packages; [ numpy scipy ];&lt;br /&gt;
      } )&lt;br /&gt;
    clang&lt;br /&gt;
  ];&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
save it in ''default.nix'' and then run &amp;lt;code&amp;gt;nix-shell&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-shell&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Now we are in a build (development) environment with all the dependencies we specified in the appropriate PATHs.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;cat $(which python3)&lt;br /&gt;
clang --version&lt;br /&gt;
python3&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;import scipy&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+d&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
To return to our standard environment we just exit the shell. This is extreamily nice if we work on many projects with conflicting dependencies.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;exit&lt;br /&gt;
cd ..&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== One-off environments ==&lt;br /&gt;
&lt;br /&gt;
Quite frequently we need a one-off development environment with a few packages.  Say CLang and git.  Rather than have to write the following boilerplate ''default.nix'' file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import &amp;amp;lt;nixpkgs&amp;amp;gt; { };&lt;br /&gt;
&lt;br /&gt;
stdenv.mkDerivation {&lt;br /&gt;
  name = &amp;amp;quot;my-env&amp;amp;quot;;&lt;br /&gt;
  buildInputs = [&lt;br /&gt;
    clang&lt;br /&gt;
    git&lt;br /&gt;
  ];&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
we can just get &amp;lt;code&amp;gt;nix-shell&amp;lt;/code&amp;gt; to do it for us.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-shell --packages clang git&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+d&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Submitting Jobs =&lt;br /&gt;
&lt;br /&gt;
Loading the Nix module before submitting a job makes the Nix environment available to the job.  Note that these jobs will see the current Nix environment including any changes made after submission.  Compiled binaries should not require the Nix module to be loaded to run.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
sqsub ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
= Internals =&lt;br /&gt;
&lt;br /&gt;
This section details some of the internals of how Nix works and how to create your own packages.  It is more advanced material not required for the basic usage.&lt;br /&gt;
== The Nix store ==&lt;br /&gt;
&lt;br /&gt;
A Nix environment is just a collection of symlinks to all the packages that exist in that environment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;readlink $(which git)&lt;br /&gt;
readlink -f ~/.nix-profile&amp;lt;/pre&amp;gt;&lt;br /&gt;
Everything in Nix exists as a path in the Nix store. Each path is distinguished with a hash of either its contents or everything that went into creating it to keep it separate from everything else. Paths are immutable once created. This means they can be freely shared.&lt;br /&gt;
&lt;br /&gt;
Paths are created by the Nix build server when it realizes a Nix derivation. Nix derivations specify all the inputs to a jailed process that creates the contents of the store path.&lt;br /&gt;
== Nix expressions and instantiation ==&lt;br /&gt;
&lt;br /&gt;
Nix derivations are instantiated from Nix expressions, which are written in the Nix language. The &amp;lt;code&amp;gt;nix-repl&amp;lt;/code&amp;gt; program can be used to interactively experiment with the Nix language.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nix-repl&lt;br /&gt;
nix-repl&amp;lt;/pre&amp;gt;&lt;br /&gt;
The following ''cabextract.nix'' Nix expression evaluates to a derivation fully specifying how to build the &amp;lt;code&amp;gt;cabextract&amp;lt;/code&amp;gt; utility.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import ~/.nix-defexpr/nixpkgs { };&lt;br /&gt;
stdenv.mkDerivation rec {&lt;br /&gt;
  name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
  src = fetchurl {&lt;br /&gt;
    url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
    sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  meta = with stdenv.lib; {&lt;br /&gt;
    homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
    description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
    platforms = platforms.all;&lt;br /&gt;
    license = licenses.gpl3;&lt;br /&gt;
    maintainers = with maintainers; [ pSub ];&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is written using the &amp;lt;code&amp;gt;stdenv.mkDerivation&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;. This function creates a derivation that executes the standard unpack, patch, configure, build, check, install, fixup, check, and distribute steps on the package. It provides a series of hooks that can be used at each step to customize the process for non-standard packages.  For full details see the [https://nixos.org/nixpkgs/manual nixpkgs manual].&lt;br /&gt;
&lt;br /&gt;
The Nix expression is instantiate to a derivation using &amp;lt;code&amp;gt;nix-instantiate&amp;lt;/code&amp;gt;. The leading ''./'' is required to distinguish that the arguments is file containing a Nix expression to be instantiated and not the name of a package in the default Nix expression to instantiate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabdrv=$(nix-instantiate ./cabextract.nix)&lt;br /&gt;
echo $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nix derivations and realization ==&lt;br /&gt;
&lt;br /&gt;
The Nix derivation instantiated from the above Nix expression can be pretty-printed using the &amp;lt;code&amp;gt;pp-aterm&amp;lt;/code&amp;gt; program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nixpkgs.strategoPackages.strategoxt&lt;br /&gt;
pp-aterm -i $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;Derive(&lt;br /&gt;
  [(&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)]&lt;br /&gt;
, [ (&amp;amp;quot;/home/nixbld/store/...-stdenv.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  ]&lt;br /&gt;
, [&amp;amp;quot;/home/nixbld/store/...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, &amp;amp;quot;x86_64-linux&amp;amp;quot;&lt;br /&gt;
, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;&lt;br /&gt;
, [&amp;amp;quot;-e&amp;amp;quot;, &amp;amp;quot;...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, [ (&amp;amp;quot;buildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;builder&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;name&amp;amp;quot;, &amp;amp;quot;cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;nativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedNativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;src&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;stdenv&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-stdenv&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;system&amp;amp;quot;, &amp;amp;quot;x86_64-linux&amp;amp;quot;)&lt;br /&gt;
  ]&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The Nix build server realizes derivations by building the packages in an isolated environment. Each derivation specifies what comes out of the environment, what goes into it, the required machine architecture, what build program to execute in the environment, and what arguments and environment to pass to the program to be executed.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program &amp;lt;code&amp;gt;--realize&amp;lt;/code&amp;gt; option is used to signal the build server to realize the derivation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabpath=$(nix-store --realize $cabdrv)&lt;br /&gt;
echo $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; program will add the realized derivation to the users environment with the &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-i&amp;lt;/code&amp;gt;) option. Technically it creates a new realization of the &amp;lt;code&amp;gt;user-environment&amp;lt;/code&amp;gt; package that symlinks in the entire contents of the path path and switches to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The build log associated with a realization can be viewed with the &amp;lt;code&amp;gt;--read-log&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-l&amp;lt;/code&amp;gt;) option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --read-log $cabdrv&lt;br /&gt;
nix-store --read-log $cabpath&lt;br /&gt;
nix-store --read-log $(which git)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program also supports numerous other store related items such as computing the transitive closure of a package with the &amp;lt;code&amp;gt;--query&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-q&amp;lt;/code&amp;gt;) &amp;lt;code&amp;gt;--requisites&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-R&amp;lt;/code&amp;gt;) and exporting them via the &amp;lt;code&amp;gt;--export&amp;lt;/code&amp;gt; option to a Nix archive for import into another store.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --query --requisites $cabpath&lt;br /&gt;
nix-store --export $(nix-store --query --requisites $(which git)) | gzip &amp;amp;gt; git.nar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Nix default expression ==&lt;br /&gt;
&lt;br /&gt;
Nix has a default expression created from the contents of ''~/.nix-defexpr''. The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; operation normally works by selecting an attribute in this expression (fast) or matching against the &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; attribute in all the attributes in this expression (slow) to determine an expression to instantiate, realize, and then symlink into a new environment.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-channel&amp;lt;/code&amp;gt; command works by building new Nix expression packages (containing all the Nix expressions for the subscribed channels) and symlinking ''~/.nix-defexprs/channels'' to then. Adding additional expressions to ''~/.nix-defexpr'' makes them available for use with &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; as well. For example, the following ''~/.nix-defexpr/mypkgs'' expression packages up the above ''cabextract.nix'' example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;args@{ ... }: with import ./nixpkgs args;&lt;br /&gt;
rec {&lt;br /&gt;
  cabextract = stdenv.mkDerivation rec {&lt;br /&gt;
    name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    src = fetchurl {&lt;br /&gt;
      url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
      sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    meta = with stdenv.lib; {&lt;br /&gt;
      homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
      description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
      platforms = platforms.all;&lt;br /&gt;
      license = licenses.gpl3;&lt;br /&gt;
      maintainers = with maintainers; [ pSub ];&lt;br /&gt;
    };&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
This makes it possible to install packages from &amp;lt;code&amp;gt;mypkgs&amp;lt;/code&amp;gt; as easily as those from the official &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr mypkgs.cabextract&amp;lt;/pre&amp;gt;&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Nix Package Manager&amp;lt;br&amp;gt;&lt;br /&gt;
http://nixos.org/nix/&lt;br /&gt;
&lt;br /&gt;
o Official Nix/Nixpkgs/NixOS&amp;lt;br&amp;gt;&lt;br /&gt;
https://github.com/NixOS&lt;br /&gt;
&lt;br /&gt;
o Nix on SHARCNET (slides by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.sharcnet.ca/help/images/5/5f/Tyson_nix_2015.pdf&lt;br /&gt;
&lt;br /&gt;
o Exploring a new approach to package management (youtube video by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.youtube.com/watch?v=pQE9WTLAPHQ&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=16229</id>
		<title>NIX</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=16229"/>
				<updated>2018-01-12T20:09:11Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Info is accurate for graham too&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=NIX&lt;br /&gt;
|package_description=User Level Purely Functional Package Manager&lt;br /&gt;
|package_idnumber=171&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
Nix is a package manager system that allows users to manage their own software environment.  This environment is persistent and is shared across all clusters.&lt;br /&gt;
&lt;br /&gt;
* Users can build, install, upgrade, downgrade, and remove packages from their environment without root privileges and without affecting other users.&lt;br /&gt;
* Operations either succeed and create a new environment or fail leaving the previous environment in place (operations are atomic).&lt;br /&gt;
* Previous environments can be switched back to at any point.&lt;br /&gt;
* Users can add their own packages and share them with other users.&lt;br /&gt;
&lt;br /&gt;
The default Nix package set includes a huge selection (over 10,000) of recent versions of many packages.&lt;br /&gt;
== Enabling and disabling the Nix environment ==&lt;br /&gt;
&lt;br /&gt;
The user's current Nix environment is enabled by loading the nix module. This creates some ''.nix*'' files and sets some environment variables.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is disabled by unloading the nix module. This unsets the environment variables but leaves the ''.nix*'' files alone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module unload nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&lt;br /&gt;
module load nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Installing and remove packages =&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; command is used to setup your Nix environment.&lt;br /&gt;
== What do I have installed and what can I install ==&lt;br /&gt;
&lt;br /&gt;
Lets first see what we currently have installed.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Now let's see what is available. We request the attribute paths (unambiguous way of specifying a package) and the descriptions too (cursor to the right to see them). This takes a bit of time as it visits a lot of small files. Especially over NFS it can be a good idea to pipe it to a file and then grep that in the future.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query --available --attr-path --description&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Installing packages ==&lt;br /&gt;
&lt;br /&gt;
Let's say that we need a newer version of git than provided by default on our OS (e.g., the CentOS 6 one has issues with fetching over https). First lets check what our OS comes with.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git --version&lt;br /&gt;
which git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let's tell Nix to install its version in our environment.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr nixpkgs.git&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let's checkout what we have now (it may be necessary to tell bash to to forget remembered executable locations with &amp;lt;code&amp;gt;hash -r&amp;lt;/code&amp;gt; so it notices the new one).&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git --version&lt;br /&gt;
which git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Removing packages ==&lt;br /&gt;
&lt;br /&gt;
For completeness, lets add in the other usual version-control suspects.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr nixpkgs.subversion nixpkgs.mercurial&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Actually, we probably don't really want subversion any more. Let's remove that.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --uninstall subversion&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Environments =&lt;br /&gt;
&lt;br /&gt;
Nix keeps referring to user environments. Each time we install or remove packages we create a new environment based off of the previous environment.&lt;br /&gt;
== Switching between previous environments ==&lt;br /&gt;
&lt;br /&gt;
This means the previous environments still exist and we can switch back to them at any point. Let's say we changed our mind and want subversion back. It's trivial to restore the previous environment.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --rollback&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Of course we may want to do more than just move to the previous environment. We can get a list of all our environments so far and then jump directly to whatever one we want. Let's undo the rollback.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --list-generations&lt;br /&gt;
nix-env --switch-generation 4&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Operations are atomic ==&lt;br /&gt;
&lt;br /&gt;
Due to the atomic property of Nix environments, we can't be left halfway through installing/updating packages. They either succeed and create us a new environment or leave us with the previous one intact.&lt;br /&gt;
&lt;br /&gt;
Let's go back to the start when we just had Nix itself and install the one true GNU distributed version control system tla. Don't let it complete though. Hit it with &amp;lt;code&amp;gt;CTRL+c&amp;lt;/code&amp;gt; partway through.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --switch-generation 1&lt;br /&gt;
nix-env --install --attr nixpkgs.tla&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+c&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Nothing bad happens. The operation didn't complete so it has no effect on the environment whatsoever.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query&lt;br /&gt;
nix-env --list-generations&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Nix only does things once ==&lt;br /&gt;
&lt;br /&gt;
The install and remove commands take the current environment and create a new environment with the changes. This works regardless of which environment we are currently in. Let's create a new environment from our original environment by just adding git and mercurial.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --list-generations&lt;br /&gt;
nix-env --install nixpkgs.git nixpkgs.mercurial&lt;br /&gt;
nix-env --list-generations&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Notice how much much faster it was to install git and mercurial the second time? That is because the software already existed in the local Nix store from the previous installs so Nix just reused it.&lt;br /&gt;
== Garbage collection ==&lt;br /&gt;
&lt;br /&gt;
Nix periodically goes through and removes any software not accessible from any existing environments. This means we have to explicitly delete environments we don't want anymore so Nix is able to reclaim the space. We can delete specific environments or any sufficiently old.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --delete-generations 30d&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Using channels to obtain Nix expressions =&lt;br /&gt;
&lt;br /&gt;
Nix packages are Nix expressions that specify how to build something. The default source for of these expression for &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; is ''~/.nix-defexp'' and ''~/.nix-defexp/channels''. Nix channels provide a way to populate this later directory with existing expressions from repositories on the internet.&lt;br /&gt;
== Subscribing to a channel ==&lt;br /&gt;
&lt;br /&gt;
By default we are subscribed to the SHARCNET version of the latest NixOS release under the name nixpkg. Let us add the older NixOS 15.09 release too under the name nixpkgs_old and then download the latest versions of all NixOS 15.09 the expressions.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-channel --list&lt;br /&gt;
nix-channel --add file:///nix/channels/sharcnet-15.09 nixpkgs_old&lt;br /&gt;
nix-channel --list&lt;br /&gt;
nix-channel --update nixpkgs_old&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Installing packages from a channel ==&lt;br /&gt;
&lt;br /&gt;
Now searching our available packages we see that we can install software using either the nixpkgs or nixpkgs_old expressions.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query --available --attr-path --description git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let's replace our git built and installed from the unstable (nixpkgs) expression with one built and installed from the stable expression (note that git is the default version of git which is gitMinimal).&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr nixpkgs_old.git&lt;br /&gt;
nix-env --query&lt;br /&gt;
git --version&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== What about dependency conflicts ==&lt;br /&gt;
&lt;br /&gt;
There are no issues with having a mix of packages installed from different sources even if they have conflicting dependencies. Nix puts each package in a separate directory under ''/nix/store'' versioned by the hash of the its build instructions. Binaries are linked with rpaths to ensure they always find the versions they need.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ldd $(readlink ($which git))&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Switching between environments continue to work as before.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --rollback&lt;br /&gt;
git --version&lt;br /&gt;
nix-env --list-generations&lt;br /&gt;
nix-env --switch-generation 5&lt;br /&gt;
git --version&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Switching between previous updates ==&lt;br /&gt;
&lt;br /&gt;
The channel updates (updating the list of expressions we can build and install from) are also atomic and versioned. This ensures we never find ourselves stuck due to accidentally updating to something broken.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-channel --rollback&lt;br /&gt;
nix-env --query --available --attr-path git&lt;br /&gt;
nix-channel --rollback 2&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Development with Nix (e.g., Python, R, etc.) =&lt;br /&gt;
&lt;br /&gt;
Several languages have their own repository of packages and associated infrastructure (e.g., PyPI and pip). Nix builds on these to automatically handle the external dependencies (e.g., C libraries) and makes it easy to work simultaneously with different projects requiring different versions of internal packages.&lt;br /&gt;
== Wrapper scripts for setting paths ==&lt;br /&gt;
&lt;br /&gt;
Nix has expressions for many of these that generate wrapper scripts that set path environment variables to bring a specific set of the internal packages into scope and then run the approriate program.&lt;br /&gt;
&lt;br /&gt;
The following Nix expression defines top-level myPython, myR, and myHaskell attributes that use the appropriate package-specific expressions to create wrappers for a selection of internal packages (for details about the Nix langauge see the [https://nixos.org/nix/manual/#ch-expression-language Nix Expression Language].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import &amp;amp;lt;nixpkgs&amp;amp;gt; { };&lt;br /&gt;
&lt;br /&gt;
rec {&lt;br /&gt;
  myPython = python3.buildEnv.override rec {&lt;br /&gt;
    extraLibs = with python3Packages; [ numpy scipy ];&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  myR = rWrapper.override rec {&lt;br /&gt;
    packages = with rPackages; [ rgeos rgdal ];&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  myHaskell = haskellPackages.ghcWithPackages (ghcpkgs:&lt;br /&gt;
    with ghcpkgs; [ pipes lens cabal-install ]&lt;br /&gt;
  );&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Saving it as ''~/.nix-defexpr/mypkgs.nix'' makes these available for installation with &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr mypkgs.myPython&lt;br /&gt;
cat $(which python3)&lt;br /&gt;
python3&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;import scipy&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+d&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
== Development environments ==&lt;br /&gt;
&lt;br /&gt;
A Nix expression evaluates to a specification for setting up a (build) environment and then doing a build in it. Frequently we want to do something very similar: setup a (development) environment and then do development in it.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-shell&amp;lt;/code&amp;gt; command bridges the gap between these two. It uses Nix to sets up a non-rooted (build) environment with the dependencies we specify and then laucnhes a (development) shell in it instead of a build process.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;mkdir devel&lt;br /&gt;
cd devel&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Say we need Clang and Python with the NumPy and SciPy packages. Instead of installing these into our global environment we can create a Nix expression that specifies these as build (development) inputs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import &amp;amp;lt;nixpkgs&amp;amp;gt; { };&lt;br /&gt;
&lt;br /&gt;
stdenv.mkDerivation {&lt;br /&gt;
  name = &amp;amp;quot;my-env&amp;amp;quot;;&lt;br /&gt;
  buildInputs = [&lt;br /&gt;
    ( python3.buildEnv.override rec {&lt;br /&gt;
        extraLibs = with python3Packages; [ numpy scipy ];&lt;br /&gt;
      } )&lt;br /&gt;
    clang&lt;br /&gt;
  ];&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
save it in ''default.nix'' and then run &amp;lt;code&amp;gt;nix-shell&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-shell&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Now we are in a build (development) environment with all the dependencies we specified in the appropriate PATHs.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;cat $(which python3)&lt;br /&gt;
clang --version&lt;br /&gt;
python3&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;import scipy&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+d&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
To return to our standard environment we just exit the shell. This is extreamily nice if we work on many projects with conflicting dependencies.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;exit&lt;br /&gt;
cd ..&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== One-off environments ==&lt;br /&gt;
&lt;br /&gt;
Quite frequently we need a one-off development environment with a few packages.  Say CLang and git.  Rather than have to write the following boilerplate ''default.nix'' file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import &amp;amp;lt;nixpkgs&amp;amp;gt; { };&lt;br /&gt;
&lt;br /&gt;
stdenv.mkDerivation {&lt;br /&gt;
  name = &amp;amp;quot;my-env&amp;amp;quot;;&lt;br /&gt;
  buildInputs = [&lt;br /&gt;
    clang&lt;br /&gt;
    git&lt;br /&gt;
  ];&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
we can just get &amp;lt;code&amp;gt;nix-shell&amp;lt;/code&amp;gt; to do it for us.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-shell --packages clang git&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+d&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Submitting Jobs =&lt;br /&gt;
&lt;br /&gt;
Loading the Nix module before submitting a job makes the Nix environment available to the job.  Note that these jobs will see the current Nix environment including any changes made after submission.  Compiled binaries should not require the Nix module to be loaded to run.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
sqsub ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
= Internals =&lt;br /&gt;
&lt;br /&gt;
This section details some of the internals of how Nix works and how to create your own packages.  It is more advanced material not required for the basic usage.&lt;br /&gt;
== The Nix store ==&lt;br /&gt;
&lt;br /&gt;
A Nix environment is just a collection of symlinks to all the packages that exist in that environment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;readlink $(which git)&lt;br /&gt;
readlink -f ~/.nix-profile&amp;lt;/pre&amp;gt;&lt;br /&gt;
Everything in Nix exists as a path in the Nix store. Each path is distinguished with a hash of either its contents or everything that went into creating it to keep it separate from everything else. Paths are immutable once created. This means they can be freely shared.&lt;br /&gt;
&lt;br /&gt;
Paths are created by the Nix build server when it realizes a Nix derivation. Nix derivations specify all the inputs to a jailed process that creates the contents of the store path.&lt;br /&gt;
== Nix expressions and instantiation ==&lt;br /&gt;
&lt;br /&gt;
Nix derivations are instantiated from Nix expressions, which are written in the Nix language. The &amp;lt;code&amp;gt;nix-repl&amp;lt;/code&amp;gt; program can be used to interactively experiment with the Nix language.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nix-repl&lt;br /&gt;
nix-repl&amp;lt;/pre&amp;gt;&lt;br /&gt;
The following ''cabextract.nix'' Nix expression evaluates to a derivation fully specifying how to build the &amp;lt;code&amp;gt;cabextract&amp;lt;/code&amp;gt; utility.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import ~/.nix-defexpr/nixpkgs { };&lt;br /&gt;
stdenv.mkDerivation rec {&lt;br /&gt;
  name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
  src = fetchurl {&lt;br /&gt;
    url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
    sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  meta = with stdenv.lib; {&lt;br /&gt;
    homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
    description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
    platforms = platforms.all;&lt;br /&gt;
    license = licenses.gpl3;&lt;br /&gt;
    maintainers = with maintainers; [ pSub ];&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is written using the &amp;lt;code&amp;gt;stdenv.mkDerivation&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;. This function creates a derivation that executes the standard unpack, patch, configure, build, check, install, fixup, check, and distribute steps on the package. It provides a series of hooks that can be used at each step to customize the process for non-standard packages.  For full details see the [https://nixos.org/nixpkgs/manual nixpkgs manual].&lt;br /&gt;
&lt;br /&gt;
The Nix expression is instantiate to a derivation using &amp;lt;code&amp;gt;nix-instantiate&amp;lt;/code&amp;gt;. The leading ''./'' is required to distinguish that the arguments is file containing a Nix expression to be instantiated and not the name of a package in the default Nix expression to instantiate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabdrv=$(nix-instantiate ./cabextract.nix)&lt;br /&gt;
echo $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nix derivations and realization ==&lt;br /&gt;
&lt;br /&gt;
The Nix derivation instantiated from the above Nix expression can be pretty-printed using the &amp;lt;code&amp;gt;pp-aterm&amp;lt;/code&amp;gt; program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nixpkgs.strategoPackages.strategoxt&lt;br /&gt;
pp-aterm -i $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;Derive(&lt;br /&gt;
  [(&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)]&lt;br /&gt;
, [ (&amp;amp;quot;/home/nixbld/store/...-stdenv.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  ]&lt;br /&gt;
, [&amp;amp;quot;/home/nixbld/store/...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, &amp;amp;quot;x86_64-linux&amp;amp;quot;&lt;br /&gt;
, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;&lt;br /&gt;
, [&amp;amp;quot;-e&amp;amp;quot;, &amp;amp;quot;...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, [ (&amp;amp;quot;buildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;builder&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;name&amp;amp;quot;, &amp;amp;quot;cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;nativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedNativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;src&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;stdenv&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-stdenv&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;system&amp;amp;quot;, &amp;amp;quot;x86_64-linux&amp;amp;quot;)&lt;br /&gt;
  ]&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The Nix build server realizes derivations by building the packages in an isolated environment. Each derivation specifies what comes out of the environment, what goes into it, the required machine architecture, what build program to execute in the environment, and what arguments and environment to pass to the program to be executed.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program &amp;lt;code&amp;gt;--realize&amp;lt;/code&amp;gt; option is used to signal the build server to realize the derivation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabpath=$(nix-store --realize $cabdrv)&lt;br /&gt;
echo $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; program will add the realized derivation to the users environment with the &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-i&amp;lt;/code&amp;gt;) option. Technically it creates a new realization of the &amp;lt;code&amp;gt;user-environment&amp;lt;/code&amp;gt; package that symlinks in the entire contents of the path path and switches to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The build log associated with a realization can be viewed with the &amp;lt;code&amp;gt;--read-log&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-l&amp;lt;/code&amp;gt;) option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --read-log $cabdrv&lt;br /&gt;
nix-store --read-log $cabpath&lt;br /&gt;
nix-store --read-log $(which git)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program also supports numerous other store related items such as computing the transitive closure of a package with the &amp;lt;code&amp;gt;--query&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-q&amp;lt;/code&amp;gt;) &amp;lt;code&amp;gt;--requisites&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-R&amp;lt;/code&amp;gt;) and exporting them via the &amp;lt;code&amp;gt;--export&amp;lt;/code&amp;gt; option to a Nix archive for import into another store.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --query --requisites $cabpath&lt;br /&gt;
nix-store --export $(nix-store --query --requisites $(which git)) | gzip &amp;amp;gt; git.nar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Nix default expression ==&lt;br /&gt;
&lt;br /&gt;
Nix has a default expression created from the contents of ''~/.nix-defexpr''. The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; operation normally works by selecting an attribute in this expression (fast) or matching against the &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; attribute in all the attributes in this expression (slow) to determine an expression to instantiate, realize, and then symlink into a new environment.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-channel&amp;lt;/code&amp;gt; command works by building new Nix expression packages (containing all the Nix expressions for the subscribed channels) and symlinking ''~/.nix-defexprs/channels'' to then. Adding additional expressions to ''~/.nix-defexpr'' makes them available for use with &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; as well. For example, the following ''~/.nix-defexpr/mypkgs'' expression packages up the above ''cabextract.nix'' example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;args@{ ... }: with import ./nixpkgs args;&lt;br /&gt;
rec {&lt;br /&gt;
  cabextract = stdenv.mkDerivation rec {&lt;br /&gt;
    name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    src = fetchurl {&lt;br /&gt;
      url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
      sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    meta = with stdenv.lib; {&lt;br /&gt;
      homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
      description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
      platforms = platforms.all;&lt;br /&gt;
      license = licenses.gpl3;&lt;br /&gt;
      maintainers = with maintainers; [ pSub ];&lt;br /&gt;
    };&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
This makes it possible to install packages from &amp;lt;code&amp;gt;mypkgs&amp;lt;/code&amp;gt; as easily as those from the official &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr mypkgs.cabextract&amp;lt;/pre&amp;gt;&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Nix Package Manager&amp;lt;br&amp;gt;&lt;br /&gt;
http://nixos.org/nix/&lt;br /&gt;
&lt;br /&gt;
o Official Nix/Nixpkgs/NixOS&amp;lt;br&amp;gt;&lt;br /&gt;
https://github.com/NixOS&lt;br /&gt;
&lt;br /&gt;
o Nix on SHARCNET (slides by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.sharcnet.ca/help/images/5/5f/Tyson_nix_2015.pdf&lt;br /&gt;
&lt;br /&gt;
o Exploring a new approach to package management (youtube video by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.youtube.com/watch?v=pQE9WTLAPHQ&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=File:Git.svg&amp;diff=14857</id>
		<title>File:Git.svg</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=File:Git.svg&amp;diff=14857"/>
				<updated>2017-02-15T19:17:05Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Tyson uploaded a new version of File:Git.svg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Git command and flow diagram&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=File:Git.svg&amp;diff=14856</id>
		<title>File:Git.svg</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=File:Git.svg&amp;diff=14856"/>
				<updated>2017-02-15T19:13:18Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Tyson uploaded a new version of File:Git.svg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Git command and flow diagram&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=14327</id>
		<title>NIX</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=14327"/>
				<updated>2016-10-05T19:14:26Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Add link to the nixpkgs manual&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=NIX&lt;br /&gt;
|package_description=User Level Purely Functional Package Manager&lt;br /&gt;
|package_idnumber=171&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
Nix is a package manager system that allows users to manage their own software environment.  This environment is persistent and is shared across all clusters.&lt;br /&gt;
&lt;br /&gt;
* Users can build, install, upgrade, downgrade, and remove packages from their environment without root privileges and without affecting other users.&lt;br /&gt;
* Operations either succeed and create a new environment or fail leaving the previous environment in place (operations are atomic).&lt;br /&gt;
* Previous environments can be switched back to at any point.&lt;br /&gt;
* Users can add their own packages and share them with other users.&lt;br /&gt;
&lt;br /&gt;
The default Nix package set includes a huge selection (over 10,000) of recent versions of many packages.&lt;br /&gt;
== Enabling and disabling the Nix environment ==&lt;br /&gt;
&lt;br /&gt;
The user's current Nix environment is enabled by loading the nix module. This creates some ''.nix*'' files and sets some environment variables.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is disabled by unloading the nix module. This unsets the environment variables but leaves the ''.nix*'' files alone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module unload nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&lt;br /&gt;
module load nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Installing and remove packages =&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; command is used to setup your Nix environment.&lt;br /&gt;
== What do I have installed and what can I install ==&lt;br /&gt;
&lt;br /&gt;
Lets first see what we currently have installed.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Now let's see what is available. We request the attribute paths (unambiguous way of specifying a package) and the descriptions too (cursor to the right to see them). This takes a bit of time as it visits a lot of small files. Especially over NFS it can be a good idea to pipe it to a file and then grep that in the future.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query --available --attr-path --description&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Installing packages ==&lt;br /&gt;
&lt;br /&gt;
Let's say that we need a newer version of git than provided by default on our OS (e.g., the CentOS 6 one has issues with fetching over https). First lets check what our OS comes with.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git --version&lt;br /&gt;
which git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let's tell Nix to install its version in our environment.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr nixpkgs.git&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let's checkout what we have now (it may be necessary to tell bash to to forget remembered executable locations with &amp;lt;code&amp;gt;hash -r&amp;lt;/code&amp;gt; so it notices the new one).&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git --version&lt;br /&gt;
which git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Removing packages ==&lt;br /&gt;
&lt;br /&gt;
For completeness, lets add in the other usual version-control suspects.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr nixpkgs.subversion nixpkgs.mercurial&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Actually, we probably don't really want subversion any more. Let's remove that.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --uninstall subversion&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Environments =&lt;br /&gt;
&lt;br /&gt;
Nix keeps referring to user environments. Each time we install or remove packages we create a new environment based off of the previous environment.&lt;br /&gt;
== Switching between previous environments ==&lt;br /&gt;
&lt;br /&gt;
This means the previous environments still exist and we can switch back to them at any point. Let's say we changed our mind and want subversion back. It's trivial to restore the previous environment.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --rollback&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Of course we may want to do more than just move to the previous environment. We can get a list of all our environments so far and then jump directly to whatever one we want. Let's undo the rollback.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --list-generations&lt;br /&gt;
nix-env --switch-generation 4&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Operations are atomic ==&lt;br /&gt;
&lt;br /&gt;
Due to the atomic property of Nix environments, we can't be left halfway through installing/updating packages. They either succeed and create us a new environment or leave us with the previous one intact.&lt;br /&gt;
&lt;br /&gt;
Let's go back to the start when we just had Nix itself and install the one true GNU distributed version control system tla. Don't let it complete though. Hit it with &amp;lt;code&amp;gt;CTRL+c&amp;lt;/code&amp;gt; partway through.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --switch-generation 1&lt;br /&gt;
nix-env --install --attr nixpkgs.tla&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+c&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Nothing bad happens. The operation didn't complete so it has no effect on the environment whatsoever.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query&lt;br /&gt;
nix-env --list-generations&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Nix only does things once ==&lt;br /&gt;
&lt;br /&gt;
The install and remove commands take the current environment and create a new environment with the changes. This works regardless of which environment we are currently in. Let's create a new environment from our original environment by just adding git and mercurial.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --list-generations&lt;br /&gt;
nix-env --install nixpkgs.git nixpkgs.mercurial&lt;br /&gt;
nix-env --list-generations&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Notice how much much faster it was to install git and mercurial the second time? That is because the software already existed in the local Nix store from the previous installs so Nix just reused it.&lt;br /&gt;
== Garbage collection ==&lt;br /&gt;
&lt;br /&gt;
Nix periodically goes through and removes any software not accessible from any existing environments. This means we have to explicitly delete environments we don't want anymore so Nix is able to reclaim the space. We can delete specific environments or any sufficiently old.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --delete-generations 30d&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Using channels to obtain Nix expressions =&lt;br /&gt;
&lt;br /&gt;
Nix packages are Nix expressions that specify how to build something. The default source for of these expression for &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; is ''~/.nix-defexp'' and ''~/.nix-defexp/channels''. Nix channels provide a way to populate this later directory with existing expressions from repositories on the internet.&lt;br /&gt;
== Subscribing to a channel ==&lt;br /&gt;
&lt;br /&gt;
By default we are subscribed to the SHARCNET version of the latest NixOS release under the name nixpkg. Let us add the older NixOS 15.09 release too under the name nixpkgs_old and then download the latest versions of all NixOS 15.09 the expressions.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-channel --list&lt;br /&gt;
nix-channel --add file:///nix/channels/sharcnet-15.09 nixpkgs_old&lt;br /&gt;
nix-channel --list&lt;br /&gt;
nix-channel --update nixpkgs_old&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Installing packages from a channel ==&lt;br /&gt;
&lt;br /&gt;
Now searching our available packages we see that we can install software using either the nixpkgs or nixpkgs_old expressions.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query --available --attr-path --description git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let's replace our git built and installed from the unstable (nixpkgs) expression with one built and installed from the stable expression (note that git is the default version of git which is gitMinimal).&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr nixpkgs_old.git&lt;br /&gt;
nix-env --query&lt;br /&gt;
git --version&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== What about dependency conflicts ==&lt;br /&gt;
&lt;br /&gt;
There are no issues with having a mix of packages installed from different sources even if they have conflicting dependencies. Nix puts each package in a separate directory under ''/nix/store'' versioned by the hash of the its build instructions. Binaries are linked with rpaths to ensure they always find the versions they need.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ldd $(readlink ($which git))&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Switching between environments continue to work as before.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --rollback&lt;br /&gt;
git --version&lt;br /&gt;
nix-env --list-generations&lt;br /&gt;
nix-env --switch-generation 5&lt;br /&gt;
git --version&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Switching between previous updates ==&lt;br /&gt;
&lt;br /&gt;
The channel updates (updating the list of expressions we can build and install from) are also atomic and versioned. This ensures we never find ourselves stuck due to accidentally updating to something broken.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-channel --rollback&lt;br /&gt;
nix-env --query --available --attr-path git&lt;br /&gt;
nix-channel --rollback 2&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Development with Nix (e.g., Python, R, etc.) =&lt;br /&gt;
&lt;br /&gt;
Several languages have their own repository of packages and associated infrastructure (e.g., PyPI and pip). Nix builds on these to automatically handle the external dependencies (e.g., C libraries) and makes it easy to work simultaneously with different projects requiring different versions of internal packages.&lt;br /&gt;
== Wrapper scripts for setting paths ==&lt;br /&gt;
&lt;br /&gt;
Nix has expressions for many of these that generate wrapper scripts that set path environment variables to bring a specific set of the internal packages into scope and then run the approriate program.&lt;br /&gt;
&lt;br /&gt;
The following Nix expression defines top-level myPython, myR, and myHaskell attributes that use the appropriate package-specific expressions to create wrappers for a selection of internal packages (for details about the Nix langauge see the [https://nixos.org/nix/manual/#ch-expression-language Nix Expression Language].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import &amp;amp;lt;nixpkgs&amp;amp;gt; { };&lt;br /&gt;
&lt;br /&gt;
rec {&lt;br /&gt;
  myPython = python3.buildEnv.override rec {&lt;br /&gt;
    extraLibs = with python3Packages; [ numpy scipy ];&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  myR = rWrapper.override rec {&lt;br /&gt;
    packages = with rPackages; [ rgeos rgdal ];&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  myHaskell = haskellPackages.ghcWithPackages (ghcpkgs:&lt;br /&gt;
    with ghcpkgs; [ pipes lens cabal-install ]&lt;br /&gt;
  );&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Saving it as ''~/.nix-defexpr/mypkgs.nix'' makes these available for installation with &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr mypkgs.myPython&lt;br /&gt;
cat $(which python3)&lt;br /&gt;
python3&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;import scipy&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+d&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
== Development environments ==&lt;br /&gt;
&lt;br /&gt;
A Nix expression evaluates to a specification for setting up a (build) environment and then doing a build in it. Frequently we want to do something very similar: setup a (development) environment and then do development in it.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-shell&amp;lt;/code&amp;gt; command bridges the gap between these two. It uses Nix to sets up a non-rooted (build) environment with the dependencies we specify and then laucnhes a (development) shell in it instead of a build process.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;mkdir devel&lt;br /&gt;
cd devel&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Say we need Clang and Python with the NumPy and SciPy packages. Instead of installing these into our global environment we can create a Nix expression that specifies these as build (development) inputs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import &amp;amp;lt;nixpkgs&amp;amp;gt; { };&lt;br /&gt;
&lt;br /&gt;
stdenv.mkDerivation {&lt;br /&gt;
  name = &amp;amp;quot;my-env&amp;amp;quot;;&lt;br /&gt;
  buildInputs = [&lt;br /&gt;
    ( python3.buildEnv.override rec {&lt;br /&gt;
        extraLibs = with python3Packages; [ numpy scipy ];&lt;br /&gt;
      } )&lt;br /&gt;
    clang&lt;br /&gt;
  ];&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
save it in ''default.nix'' and then run &amp;lt;code&amp;gt;nix-shell&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-shell&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Now we are in a build (development) environment with all the dependencies we specified in the appropriate PATHs.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;cat $(which python3)&lt;br /&gt;
clang --version&lt;br /&gt;
python3&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;import scipy&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+d&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
To return to our standard environment we just exit the shell. This is extreamily nice if we work on many projects with conflicting dependencies.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;exit&lt;br /&gt;
cd ..&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== One-off environments ==&lt;br /&gt;
&lt;br /&gt;
Quite frequently we need a one-off development environment with a few packages.  Say CLang and git.  Rather than have to write the following boilerplate ''default.nix'' file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import &amp;amp;lt;nixpkgs&amp;amp;gt; { };&lt;br /&gt;
&lt;br /&gt;
stdenv.mkDerivation {&lt;br /&gt;
  name = &amp;amp;quot;my-env&amp;amp;quot;;&lt;br /&gt;
  buildInputs = [&lt;br /&gt;
    clang&lt;br /&gt;
    git&lt;br /&gt;
  ];&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
we can just get &amp;lt;code&amp;gt;nix-shell&amp;lt;/code&amp;gt; to do it for us.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-shell --packages clang git&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+d&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Submitting Jobs =&lt;br /&gt;
&lt;br /&gt;
Loading the Nix module before submitting a job makes the Nix environment available to the job.  Note that these jobs will see the current Nix environment including any changes made after submission.  Compiled binaries should not require the Nix module to be loaded to run.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
sqsub ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
= Internals =&lt;br /&gt;
&lt;br /&gt;
This section details some of the internals of how Nix works and how to create your own packages.  It is more advanced material not required for the basic usage.&lt;br /&gt;
== The Nix store ==&lt;br /&gt;
&lt;br /&gt;
A Nix environment is just a collection of symlinks to all the packages that exist in that environment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;readlink $(which git)&lt;br /&gt;
readlink -f ~/.nix-profile&amp;lt;/pre&amp;gt;&lt;br /&gt;
Everything in Nix exists as a path in the Nix store. Each path is distinguished with a hash of either its contents or everything that went into creating it to keep it separate from everything else. Paths are immutable once created. This means they can be freely shared.&lt;br /&gt;
&lt;br /&gt;
Paths are created by the Nix build server when it realizes a Nix derivation. Nix derivations specify all the inputs to a jailed process that creates the contents of the store path.&lt;br /&gt;
== Nix expressions and instantiation ==&lt;br /&gt;
&lt;br /&gt;
Nix derivations are instantiated from Nix expressions, which are written in the Nix language. The &amp;lt;code&amp;gt;nix-repl&amp;lt;/code&amp;gt; program can be used to interactively experiment with the Nix language.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nix-repl&lt;br /&gt;
nix-repl&amp;lt;/pre&amp;gt;&lt;br /&gt;
The following ''cabextract.nix'' Nix expression evaluates to a derivation fully specifying how to build the &amp;lt;code&amp;gt;cabextract&amp;lt;/code&amp;gt; utility.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import ~/.nix-defexpr/nixpkgs { };&lt;br /&gt;
stdenv.mkDerivation rec {&lt;br /&gt;
  name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
  src = fetchurl {&lt;br /&gt;
    url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
    sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  meta = with stdenv.lib; {&lt;br /&gt;
    homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
    description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
    platforms = platforms.all;&lt;br /&gt;
    license = licenses.gpl3;&lt;br /&gt;
    maintainers = with maintainers; [ pSub ];&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is written using the &amp;lt;code&amp;gt;stdenv.mkDerivation&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;. This function creates a derivation that executes the standard unpack, patch, configure, build, check, install, fixup, check, and distribute steps on the package. It provides a series of hooks that can be used at each step to customize the process for non-standard packages.  For full details see the [https://nixos.org/nixpkgs/manual nixpkgs manual].&lt;br /&gt;
&lt;br /&gt;
The Nix expression is instantiate to a derivation using &amp;lt;code&amp;gt;nix-instantiate&amp;lt;/code&amp;gt;. The leading ''./'' is required to distinguish that the arguments is file containing a Nix expression to be instantiated and not the name of a package in the default Nix expression to instantiate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabdrv=$(nix-instantiate ./cabextract.nix)&lt;br /&gt;
echo $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nix derivations and realization ==&lt;br /&gt;
&lt;br /&gt;
The Nix derivation instantiated from the above Nix expression can be pretty-printed using the &amp;lt;code&amp;gt;pp-aterm&amp;lt;/code&amp;gt; program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nixpkgs.strategoPackages.strategoxt&lt;br /&gt;
pp-aterm -i $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;Derive(&lt;br /&gt;
  [(&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)]&lt;br /&gt;
, [ (&amp;amp;quot;/home/nixbld/store/...-stdenv.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  ]&lt;br /&gt;
, [&amp;amp;quot;/home/nixbld/store/...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, &amp;amp;quot;x86_64-linux&amp;amp;quot;&lt;br /&gt;
, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;&lt;br /&gt;
, [&amp;amp;quot;-e&amp;amp;quot;, &amp;amp;quot;...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, [ (&amp;amp;quot;buildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;builder&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;name&amp;amp;quot;, &amp;amp;quot;cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;nativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedNativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;src&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;stdenv&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-stdenv&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;system&amp;amp;quot;, &amp;amp;quot;x86_64-linux&amp;amp;quot;)&lt;br /&gt;
  ]&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The Nix build server realizes derivations by building the packages in an isolated environment. Each derivation specifies what comes out of the environment, what goes into it, the required machine architecture, what build program to execute in the environment, and what arguments and environment to pass to the program to be executed.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program &amp;lt;code&amp;gt;--realize&amp;lt;/code&amp;gt; option is used to signal the build server to realize the derivation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabpath=$(nix-store --realize $cabdrv)&lt;br /&gt;
echo $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; program will add the realized derivation to the users environment with the &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-i&amp;lt;/code&amp;gt;) option. Technically it creates a new realization of the &amp;lt;code&amp;gt;user-environment&amp;lt;/code&amp;gt; package that symlinks in the entire contents of the path path and switches to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The build log associated with a realization can be viewed with the &amp;lt;code&amp;gt;--read-log&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-l&amp;lt;/code&amp;gt;) option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --read-log $cabdrv&lt;br /&gt;
nix-store --read-log $cabpath&lt;br /&gt;
nix-store --read-log $(which git)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program also supports numerous other store related items such as computing the transitive closure of a package with the &amp;lt;code&amp;gt;--query&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-q&amp;lt;/code&amp;gt;) &amp;lt;code&amp;gt;--requisites&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-R&amp;lt;/code&amp;gt;) and exporting them via the &amp;lt;code&amp;gt;--export&amp;lt;/code&amp;gt; option to a Nix archive for import into another store.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --query --requisites $cabpath&lt;br /&gt;
nix-store --export $(nix-store --query --requisites $(which git)) | gzip &amp;amp;gt; git.nar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Nix default expression ==&lt;br /&gt;
&lt;br /&gt;
Nix has a default expression created from the contents of ''~/.nix-defexpr''. The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; operation normally works by selecting an attribute in this expression (fast) or matching against the &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; attribute in all the attributes in this expression (slow) to determine an expression to instantiate, realize, and then symlink into a new environment.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-channel&amp;lt;/code&amp;gt; command works by building new Nix expression packages (containing all the Nix expressions for the subscribed channels) and symlinking ''~/.nix-defexprs/channels'' to then. Adding additional expressions to ''~/.nix-defexpr'' makes them available for use with &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; as well. For example, the following ''~/.nix-defexpr/mypkgs'' expression packages up the above ''cabextract.nix'' example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;args@{ ... }: with import ./nixpkgs args;&lt;br /&gt;
rec {&lt;br /&gt;
  cabextract = stdenv.mkDerivation rec {&lt;br /&gt;
    name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    src = fetchurl {&lt;br /&gt;
      url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
      sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    meta = with stdenv.lib; {&lt;br /&gt;
      homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
      description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
      platforms = platforms.all;&lt;br /&gt;
      license = licenses.gpl3;&lt;br /&gt;
      maintainers = with maintainers; [ pSub ];&lt;br /&gt;
    };&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
This makes it possible to install packages from &amp;lt;code&amp;gt;mypkgs&amp;lt;/code&amp;gt; as easily as those from the official &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr mypkgs.cabextract&amp;lt;/pre&amp;gt;&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Nix Package Manager&amp;lt;br&amp;gt;&lt;br /&gt;
http://nixos.org/nix/&lt;br /&gt;
&lt;br /&gt;
o Official Nix/Nixpkgs/NixOS&amp;lt;br&amp;gt;&lt;br /&gt;
https://github.com/NixOS&lt;br /&gt;
&lt;br /&gt;
o Nix on SHARCNET (slides by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.sharcnet.ca/help/images/5/5f/Tyson_nix_2015.pdf&lt;br /&gt;
&lt;br /&gt;
o Exploring a new approach to package management (youtube video by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.youtube.com/watch?v=pQE9WTLAPHQ&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=File:Git.svg&amp;diff=13572</id>
		<title>File:Git.svg</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=File:Git.svg&amp;diff=13572"/>
				<updated>2016-05-11T21:19:40Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Git command and flow diagram&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Git command and flow diagram&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=13531</id>
		<title>NIX</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=13531"/>
				<updated>2016-04-18T18:40:01Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Simplified intro recommended by Fraser&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=NIX&lt;br /&gt;
|package_description=User Level Purely Functional Package Manager&lt;br /&gt;
|package_idnumber=171&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
Nix is a package manager system that allows users to manage their own software environment.  This environment is persistent and is shared across all clusters.&lt;br /&gt;
&lt;br /&gt;
* Users can build, install, upgrade, downgrade, and remove packages from their environment without root privileges and without affecting other users.&lt;br /&gt;
* Operations either succeed and create a new environment or fail leaving the previous environment in place (operations are atomic).&lt;br /&gt;
* Previous environments can be switched back to at any point.&lt;br /&gt;
* Users can add their own packages and share them with other users.&lt;br /&gt;
&lt;br /&gt;
The default Nix package set includes a huge selection (over 10,000) of recent versions of many packages.&lt;br /&gt;
== Enabling and disabling the Nix environment ==&lt;br /&gt;
&lt;br /&gt;
The user's current Nix environment is enabled by loading the nix module. This creates some ''.nix*'' files and sets some environment variables.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is disabled by unloading the nix module. This unsets the environment variables but leaves the ''.nix*'' files alone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module unload nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&lt;br /&gt;
module load nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Installing and remove packages =&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; command is used to setup your Nix environment.&lt;br /&gt;
== What do I have installed and what can I install ==&lt;br /&gt;
&lt;br /&gt;
Lets first see what we currently have installed.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Now let's see what is available. We request the attribute paths (unambiguous way of specifying a package) and the descriptions too (cursor to the right to see them). This takes a bit of time as it visits a lot of small files. Especially over NFS it can be a good idea to pipe it to a file and then grep that in the future.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query --available --attr-path --description&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Installing packages ==&lt;br /&gt;
&lt;br /&gt;
Let's say that we need a newer version of git than provided by default on our OS (e.g., the CentOS 6 one has issues with fetching over https). First lets check what our OS comes with.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git --version&lt;br /&gt;
which git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let's tell Nix to install its version in our environment.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr nixpkgs.git&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let's checkout what we have now (it may be necessary to tell bash to to forget remembered executable locations with &amp;lt;code&amp;gt;hash -r&amp;lt;/code&amp;gt; so it notices the new one).&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git --version&lt;br /&gt;
which git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Removing packages ==&lt;br /&gt;
&lt;br /&gt;
For completeness, lets add in the other usual version-control suspects.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr nixpkgs.subversion nixpkgs.mercurial&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Actually, we probably don't really want subversion any more. Let's remove that.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --uninstall subversion&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Environments =&lt;br /&gt;
&lt;br /&gt;
Nix keeps referring to user environments. Each time we install or remove packages we create a new environment based off of the previous environment.&lt;br /&gt;
== Switching between previous environments ==&lt;br /&gt;
&lt;br /&gt;
This means the previous environments still exist and we can switch back to them at any point. Let's say we changed our mind and want subversion back. It's trivial to restore the previous environment.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --rollback&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Of course we may want to do more than just move to the previous environment. We can get a list of all our environments so far and then jump directly to whatever one we want. Let's undo the rollback.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --list-generations&lt;br /&gt;
nix-env --switch-generation 4&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Operations are atomic ==&lt;br /&gt;
&lt;br /&gt;
Due to the atomic property of Nix environments, we can't be left halfway through installing/updating packages. They either succeed and create us a new environment or leave us with the previous one intact.&lt;br /&gt;
&lt;br /&gt;
Let's go back to the start when we just had Nix itself and install the one true GNU distributed version control system tla. Don't let it complete though. Hit it with &amp;lt;code&amp;gt;CTRL+c&amp;lt;/code&amp;gt; partway through.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --switch-generation 1&lt;br /&gt;
nix-env --install --attr nixpkgs.tla&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+c&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Nothing bad happens. The operation didn't complete so it has no effect on the environment whatsoever.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query&lt;br /&gt;
nix-env --list-generations&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Nix only does things once ==&lt;br /&gt;
&lt;br /&gt;
The install and remove commands take the current environment and create a new environment with the changes. This works regardless of which environment we are currently in. Let's create a new environment from our original environment by just adding git and mercurial.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --list-generations&lt;br /&gt;
nix-env --install nixpkgs.git nixpkgs.mercurial&lt;br /&gt;
nix-env --list-generations&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Notice how much much faster it was to install git and mercurial the second time? That is because the software already existed in the local Nix store from the previous installs so Nix just reused it.&lt;br /&gt;
== Garbage collection ==&lt;br /&gt;
&lt;br /&gt;
Nix periodically goes through and removes any software not accessible from any existing environments. This means we have to explicitly delete environments we don't want anymore so Nix is able to reclaim the space. We can delete specific environments or any sufficiently old.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --delete-generations 30d&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Using channels to obtain Nix expressions =&lt;br /&gt;
&lt;br /&gt;
Nix packages are Nix expressions that specify how to build something. The default source for of these expression for &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; is ''~/.nix-defexp'' and ''~/.nix-defexp/channels''. Nix channels provide a way to populate this later directory with existing expressions from repositories on the internet.&lt;br /&gt;
== Subscribing to a channel ==&lt;br /&gt;
&lt;br /&gt;
By default we are subscribed to the SHARCNET version of the latest NixOS release under the name nixpkg. Let us add the older NixOS 15.09 release too under the name nixpkgs_old and then download the latest versions of all NixOS 15.09 the expressions.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-channel --list&lt;br /&gt;
nix-channel --add file:///nix/channels/sharcnet-15.09 nixpkgs_old&lt;br /&gt;
nix-channel --list&lt;br /&gt;
nix-channel --update nixpkgs_old&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Installing packages from a channel ==&lt;br /&gt;
&lt;br /&gt;
Now searching our available packages we see that we can install software using either the nixpkgs or nixpkgs_old expressions.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query --available --attr-path --description git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let's replace our git built and installed from the unstable (nixpkgs) expression with one built and installed from the stable expression (note that git is the default version of git which is gitMinimal).&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr nixpkgs_old.git&lt;br /&gt;
nix-env --query&lt;br /&gt;
git --version&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== What about dependency conflicts ==&lt;br /&gt;
&lt;br /&gt;
There are no issues with having a mix of packages installed from different sources even if they have conflicting dependencies. Nix puts each package in a separate directory under ''/nix/store'' versioned by the hash of the its build instructions. Binaries are linked with rpaths to ensure they always find the versions they need.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ldd $(readlink ($which git))&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Switching between environments continue to work as before.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --rollback&lt;br /&gt;
git --version&lt;br /&gt;
nix-env --list-generations&lt;br /&gt;
nix-env --switch-generation 5&lt;br /&gt;
git --version&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Switching between previous updates ==&lt;br /&gt;
&lt;br /&gt;
The channel updates (updating the list of expressions we can build and install from) are also atomic and versioned. This ensures we never find ourselves stuck due to accidentally updating to something broken.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-channel --rollback&lt;br /&gt;
nix-env --query --available --attr-path git&lt;br /&gt;
nix-channel --rollback 2&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Development with Nix (e.g., Python, R, etc.) =&lt;br /&gt;
&lt;br /&gt;
Several languages have their own repository of packages and associated infrastructure (e.g., PyPI and pip). Nix builds on these to automatically handle the external dependencies (e.g., C libraries) and makes it easy to work simultaneously with different projects requiring different versions of internal packages.&lt;br /&gt;
== Wrapper scripts for setting paths ==&lt;br /&gt;
&lt;br /&gt;
Nix has expressions for many of these that generate wrapper scripts that set path environment variables to bring a specific set of the internal packages into scope and then run the approriate program.&lt;br /&gt;
&lt;br /&gt;
The following Nix expression defines top-level myPython, myR, and myHaskell attributes that use the appropriate package-specific expressions to create wrappers for a selection of internal packages (for details about the Nix langauge see the [https://nixos.org/nix/manual/#ch-expression-language Nix Expression Language].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import &amp;amp;lt;nixpkgs&amp;amp;gt; { };&lt;br /&gt;
&lt;br /&gt;
rec {&lt;br /&gt;
  myPython = python3.buildEnv.override rec {&lt;br /&gt;
    extraLibs = with python3Packages; [ numpy scipy ];&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  myR = rWrapper.override rec {&lt;br /&gt;
    packages = with rPackages; [ rgeos rgdal ];&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  myHaskell = haskellPackages.ghcWithPackages (ghcpkgs:&lt;br /&gt;
    with ghcpkgs; [ pipes lens cabal-install ]&lt;br /&gt;
  );&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Saving it as ''~/.nix-defexpr/mypkgs.nix'' makes these available for installation with &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr mypkgs.myPython&lt;br /&gt;
cat $(which python3)&lt;br /&gt;
python3&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;import scipy&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+d&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
== Development environments ==&lt;br /&gt;
&lt;br /&gt;
A Nix expression evaluates to a specification for setting up a (build) environment and then doing a build in it. Frequently we want to do something very similar: setup a (development) environment and then do development in it.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-shell&amp;lt;/code&amp;gt; command bridges the gap between these two. It uses Nix to sets up a non-rooted (build) environment with the dependencies we specify and then laucnhes a (development) shell in it instead of a build process.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;mkdir devel&lt;br /&gt;
cd devel&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Say we need Clang and Python with the NumPy and SciPy packages. Instead of installing these into our global environment we can create a Nix expression that specifies these as build (development) inputs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import &amp;amp;lt;nixpkgs&amp;amp;gt; { };&lt;br /&gt;
&lt;br /&gt;
stdenv.mkDerivation {&lt;br /&gt;
  name = &amp;amp;quot;my-env&amp;amp;quot;;&lt;br /&gt;
  buildInputs = [&lt;br /&gt;
    ( python3.buildEnv.override rec {&lt;br /&gt;
        extraLibs = with python3Packages; [ numpy scipy ];&lt;br /&gt;
      } )&lt;br /&gt;
    clang&lt;br /&gt;
  ];&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
save it in ''default.nix'' and then run &amp;lt;code&amp;gt;nix-shell&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-shell&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Now we are in a build (development) environment with all the dependencies we specified in the appropriate PATHs.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;cat $(which python3)&lt;br /&gt;
clang --version&lt;br /&gt;
python3&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;import scipy&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+d&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
To return to our standard environment we just exit the shell. This is extreamily nice if we work on many projects with conflicting dependencies.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;exit&lt;br /&gt;
cd ..&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== One-off environments ==&lt;br /&gt;
&lt;br /&gt;
Quite frequently we need a one-off development environment with a few packages.  Say CLang and git.  Rather than have to write the following boilerplate ''default.nix'' file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import &amp;amp;lt;nixpkgs&amp;amp;gt; { };&lt;br /&gt;
&lt;br /&gt;
stdenv.mkDerivation {&lt;br /&gt;
  name = &amp;amp;quot;my-env&amp;amp;quot;;&lt;br /&gt;
  buildInputs = [&lt;br /&gt;
    clang&lt;br /&gt;
    git&lt;br /&gt;
  ];&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
we can just get &amp;lt;code&amp;gt;nix-shell&amp;lt;/code&amp;gt; to do it for us.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-shell --packages clang git&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+d&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Submitting Jobs =&lt;br /&gt;
&lt;br /&gt;
Loading the Nix module before submitting a job makes the Nix environment available to the job.  Note that these jobs will see the current Nix environment including any changes made after submission.  Compiled binaries should not require the Nix module to be loaded to run.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
sqsub ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
= Internals =&lt;br /&gt;
&lt;br /&gt;
This section details some of the internals of how Nix works and how to create your own packages.  It is more advanced material not required for the basic usage.&lt;br /&gt;
== The Nix store ==&lt;br /&gt;
&lt;br /&gt;
A Nix environment is just a collection of symlinks to all the packages that exist in that environment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;readlink $(which git)&lt;br /&gt;
readlink -f ~/.nix-profile&amp;lt;/pre&amp;gt;&lt;br /&gt;
Everything in Nix exists as a path in the Nix store. Each path is distinguished with a hash of either its contents or everything that went into creating it to keep it separate from everything else. Paths are immutable once created. This means they can be freely shared.&lt;br /&gt;
&lt;br /&gt;
Paths are created by the Nix build server when it realizes a Nix derivation. Nix derivations specify all the inputs to a jailed process that creates the contents of the store path.&lt;br /&gt;
== Nix expressions and instantiation ==&lt;br /&gt;
&lt;br /&gt;
Nix derivations are instantiated from Nix expressions, which are written in the Nix language. The &amp;lt;code&amp;gt;nix-repl&amp;lt;/code&amp;gt; program can be used to interactively experiment with the Nix language.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nix-repl&lt;br /&gt;
nix-repl&amp;lt;/pre&amp;gt;&lt;br /&gt;
The following ''cabextract.nix'' Nix expression evaluates to a derivation fully specifying how to build the &amp;lt;code&amp;gt;cabextract&amp;lt;/code&amp;gt; utility.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import ~/.nix-defexpr/nixpkgs { };&lt;br /&gt;
stdenv.mkDerivation rec {&lt;br /&gt;
  name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
  src = fetchurl {&lt;br /&gt;
    url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
    sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  meta = with stdenv.lib; {&lt;br /&gt;
    homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
    description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
    platforms = platforms.all;&lt;br /&gt;
    license = licenses.gpl3;&lt;br /&gt;
    maintainers = with maintainers; [ pSub ];&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is written using the &amp;lt;code&amp;gt;stdenv.mkDerivation&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;. This function creates a derivation that executes the standard unpack, patch, configure, build, check, install, fixup, check, and distribute steps on the package. It provides a series of hooks that can be used at each step to customize the process for non-standard packages.&lt;br /&gt;
&lt;br /&gt;
The Nix expression is instantiate to a derivation using &amp;lt;code&amp;gt;nix-instantiate&amp;lt;/code&amp;gt;. The leading ''./'' is required to distinguish that the arguments is file containing a Nix expression to be instantiated and not the name of a package in the default Nix expression to instantiate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabdrv=$(nix-instantiate ./cabextract.nix)&lt;br /&gt;
echo $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Nix derivations and realization ==&lt;br /&gt;
&lt;br /&gt;
The Nix derivation instantiated from the above Nix expression can be pretty-printed using the &amp;lt;code&amp;gt;pp-aterm&amp;lt;/code&amp;gt; program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nixpkgs.strategoPackages.strategoxt&lt;br /&gt;
pp-aterm -i $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;Derive(&lt;br /&gt;
  [(&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)]&lt;br /&gt;
, [ (&amp;amp;quot;/home/nixbld/store/...-stdenv.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  ]&lt;br /&gt;
, [&amp;amp;quot;/home/nixbld/store/...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, &amp;amp;quot;x86_64-linux&amp;amp;quot;&lt;br /&gt;
, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;&lt;br /&gt;
, [&amp;amp;quot;-e&amp;amp;quot;, &amp;amp;quot;...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, [ (&amp;amp;quot;buildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;builder&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;name&amp;amp;quot;, &amp;amp;quot;cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;nativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedNativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;src&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;stdenv&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-stdenv&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;system&amp;amp;quot;, &amp;amp;quot;x86_64-linux&amp;amp;quot;)&lt;br /&gt;
  ]&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The Nix build server realizes derivations by building the packages in an isolated environment. Each derivation specifies what comes out of the environment, what goes into it, the required machine architecture, what build program to execute in the environment, and what arguments and environment to pass to the program to be executed.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program &amp;lt;code&amp;gt;--realize&amp;lt;/code&amp;gt; option is used to signal the build server to realize the derivation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabpath=$(nix-store --realize $cabdrv)&lt;br /&gt;
echo $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; program will add the realized derivation to the users environment with the &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-i&amp;lt;/code&amp;gt;) option. Technically it creates a new realization of the &amp;lt;code&amp;gt;user-environment&amp;lt;/code&amp;gt; package that symlinks in the entire contents of the path path and switches to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The build log associated with a realization can be viewed with the &amp;lt;code&amp;gt;--read-log&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-l&amp;lt;/code&amp;gt;) option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --read-log $cabdrv&lt;br /&gt;
nix-store --read-log $cabpath&lt;br /&gt;
nix-store --read-log $(which git)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program also supports numerous other store related items such as computing the transitive closure of a package with the &amp;lt;code&amp;gt;--query&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-q&amp;lt;/code&amp;gt;) &amp;lt;code&amp;gt;--requisites&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-R&amp;lt;/code&amp;gt;) and exporting them via the &amp;lt;code&amp;gt;--export&amp;lt;/code&amp;gt; option to a Nix archive for import into another store.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --query --requisites $cabpath&lt;br /&gt;
nix-store --export $(nix-store --query --requisites $(which git)) | gzip &amp;amp;gt; git.nar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Nix default expression ==&lt;br /&gt;
&lt;br /&gt;
Nix has a default expression created from the contents of ''~/.nix-defexpr''. The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; operation normally works by selecting an attribute in this expression (fast) or matching against the &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; attribute in all the attributes in this expression (slow) to determine an expression to instantiate, realize, and then symlink into a new environment.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-channel&amp;lt;/code&amp;gt; command works by building new Nix expression packages (containing all the Nix expressions for the subscribed channels) and symlinking ''~/.nix-defexprs/channels'' to then. Adding additional expressions to ''~/.nix-defexpr'' makes them available for use with &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; as well. For example, the following ''~/.nix-defexpr/mypkgs'' expression packages up the above ''cabextract.nix'' example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;args@{ ... }: with import ./nixpkgs args;&lt;br /&gt;
rec {&lt;br /&gt;
  cabextract = stdenv.mkDerivation rec {&lt;br /&gt;
    name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    src = fetchurl {&lt;br /&gt;
      url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
      sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    meta = with stdenv.lib; {&lt;br /&gt;
      homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
      description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
      platforms = platforms.all;&lt;br /&gt;
      license = licenses.gpl3;&lt;br /&gt;
      maintainers = with maintainers; [ pSub ];&lt;br /&gt;
    };&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
This makes it possible to install packages from &amp;lt;code&amp;gt;mypkgs&amp;lt;/code&amp;gt; as easily as those from the official &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr mypkgs.cabextract&amp;lt;/pre&amp;gt;&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Nix Package Manager&amp;lt;br&amp;gt;&lt;br /&gt;
http://nixos.org/nix/&lt;br /&gt;
&lt;br /&gt;
o Official Nix/Nixpkgs/NixOS&amp;lt;br&amp;gt;&lt;br /&gt;
https://github.com/NixOS&lt;br /&gt;
&lt;br /&gt;
o Nix on SHARCNET (slides by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.sharcnet.ca/help/images/5/5f/Tyson_nix_2015.pdf&lt;br /&gt;
&lt;br /&gt;
o Exploring a new approach to package management (youtube video by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.youtube.com/watch?v=pQE9WTLAPHQ&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=13524</id>
		<title>NIX</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=13524"/>
				<updated>2016-04-14T21:12:39Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Add section on one-off environments&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=NIX&lt;br /&gt;
|package_description=User Level Purely Functional Package Manager&lt;br /&gt;
|package_idnumber=171&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
Nix is an atomic pure non-mutable package manager system that allows users to manage their own software environment.  This environment is persistent and is shared across all clusters.&lt;br /&gt;
&lt;br /&gt;
* Users can build, install, upgrade, downgrade, and remove packages from their environment without root privileges and without affecting other users&lt;br /&gt;
* Operations are atomic, they either succeed and create a new environment or fail leaving the previous environment in place.  Previous environments can be switched back to at any point.&lt;br /&gt;
&lt;br /&gt;
The default Nix package set includes a huge selection (over 10,000) of recent versions of many packages.&lt;br /&gt;
== Enabling and disabling the Nix environment ==&lt;br /&gt;
&lt;br /&gt;
The user's current Nix environment is enabled by loading the nix module. This creates some ''.nix*'' files and sets some environment variables.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is disabled by unloading the nix module. This unsets the environment variables but leaves the ''.nix*'' files alone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module unload nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&lt;br /&gt;
module load nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
= Installing and remove packages =&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; command is used to setup your Nix environment.&lt;br /&gt;
== What do I have installed and what can I install ==&lt;br /&gt;
&lt;br /&gt;
Lets first see what we currently have installed.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Now let's see what is available. We request the attribute paths (unambiguous way of specifying a package) and the descriptions too (cursor to the right to see them). This takes a bit of time as it visits a lot of small files. Especially over NFS it can be a good idea to pipe it to a file and then grep that in the future.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query --available --attr-path --description&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Installing packages ==&lt;br /&gt;
&lt;br /&gt;
Let's say that we need a newer version of git than provided by default on our OS (e.g., the CentOS 6 one has issues with fetching over https). First lets check what our OS comes with.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git --version&lt;br /&gt;
which git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let's tell Nix to install its version in our environment.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr nixpkgs.git&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let's checkout what we have now (it may be necessary to tell bash to to forget remembered executable locations with &amp;lt;code&amp;gt;hash -r&amp;lt;/code&amp;gt; so it notices the new one).&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git --version&lt;br /&gt;
which git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Removing packages ==&lt;br /&gt;
&lt;br /&gt;
For completeness, lets add in the other usual version-control suspects.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr nixpkgs.subversion nixpkgs.mercurial&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Actually, we probably don't really want subversion any more. Let's remove that.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --uninstall subversion&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Environments =&lt;br /&gt;
&lt;br /&gt;
Nix keeps referring to user environments. Each time we install or remove packages we create a new environment based off of the previous environment.&lt;br /&gt;
== Switching between previous environments ==&lt;br /&gt;
&lt;br /&gt;
This means the previous environments still exist and we can switch back to them at any point. Let's say we changed our mind and want subversion back. It's trivial to restore the previous environment.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --rollback&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Of course we may want to do more than just move to the previous environment. We can get a list of all our environments so far and then jump directly to whatever one we want. Let's undo the rollback.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --list-generations&lt;br /&gt;
nix-env --switch-generation 4&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Operations are atomic ==&lt;br /&gt;
&lt;br /&gt;
Due to the atomic property of Nix environments, we can't be left halfway through installing/updating packages. They either succeed and create us a new environment or leave us with the previous one intact.&lt;br /&gt;
&lt;br /&gt;
Let's go back to the start when we just had Nix itself and install the one true GNU distributed version control system tla. Don't let it complete though. Hit it with &amp;lt;code&amp;gt;CTRL+c&amp;lt;/code&amp;gt; partway through.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --switch-generation 1&lt;br /&gt;
nix-env --install --attr nixpkgs.tla&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+c&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Nothing bad happens. The operation didn't complete so it has no effect on the environment whatsoever.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query&lt;br /&gt;
nix-env --list-generations&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Nix only does things once ==&lt;br /&gt;
&lt;br /&gt;
The install and remove commands take the current environment and create a new environment with the changes. This works regardless of which environment we are currently in. Let's create a new environment from our original environment by just adding git and mercurial.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --list-generations&lt;br /&gt;
nix-env --install nixpkgs.git nixpkgs.mercurial&lt;br /&gt;
nix-env --list-generations&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Notice how much much faster it was to install git and mercurial the second time? That is because the software already existed in the local Nix store from the previous installs so Nix just reused it.&lt;br /&gt;
== Garbage collection ==&lt;br /&gt;
&lt;br /&gt;
Nix periodically goes through and removes any software not accessible from any existing environments. This means we have to explicitly delete environments we don't want anymore so Nix is able to reclaim the space. We can delete specific environments or any sufficiently old.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --delete-generations 30d&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Using channels to obtain Nix expressions =&lt;br /&gt;
&lt;br /&gt;
Nix packages are Nix expressions that specify how to build something. The default source for of these expression for &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; is ''~/.nix-defexp'' and ''~/.nix-defexp/channels''. Nix channels provide a way to populate this later directory with existing expressions from repositories on the internet.&lt;br /&gt;
== Subscribing to a channel ==&lt;br /&gt;
&lt;br /&gt;
By default we are subscribed to the SHARCNET version of the latest NixOS release under the name nixpkg. Let us add the older NixOS 15.09 release too under the name nixpkgs_old and then download the latest versions of all NixOS 15.09 the expressions.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-channel --list&lt;br /&gt;
nix-channel --add file:///nix/channels/sharcnet-15.09 nixpkgs_old&lt;br /&gt;
nix-channel --list&lt;br /&gt;
nix-channel --update nixpkgs_old&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Installing packages from a channel ==&lt;br /&gt;
&lt;br /&gt;
Now searching our available packages we see that we can install software using either the nixpkgs or nixpkgs_old expressions.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query --available --attr-path --description git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let's replace our git built and installed from the unstable (nixpkgs) expression with one built and installed from the stable expression (note that git is the default version of git which is gitMinimal).&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr nixpkgs_old.git&lt;br /&gt;
nix-env --query&lt;br /&gt;
git --version&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== What about dependency conflicts ==&lt;br /&gt;
&lt;br /&gt;
There are no issues with having a mix of packages installed from different sources even if they have conflicting dependencies. Nix puts each package in a separate directory under ''/nix/store'' versioned by the hash of the its build instructions. Binaries are linked with rpaths to ensure they always find the versions they need.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ldd $(readlink ($which git))&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Switching between environments continue to work as before.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --rollback&lt;br /&gt;
git --version&lt;br /&gt;
nix-env --list-generations&lt;br /&gt;
nix-env --switch-generation 5&lt;br /&gt;
git --version&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Switching between previous updates ==&lt;br /&gt;
&lt;br /&gt;
The channel updates (updating the list of expressions we can build and install from) are also atomic and versioned. This ensures we never find ourselves stuck due to accidentally updating to something broken.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-channel --rollback&lt;br /&gt;
nix-env --query --available --attr-path git&lt;br /&gt;
nix-channel --rollback 2&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Development with Nix (e.g., Python, R, etc.) =&lt;br /&gt;
&lt;br /&gt;
Several languages have their own repository of packages and associated infrastructure (e.g., PyPI and pip). Nix builds on these to automatically handle the external dependencies (e.g., C libraries) and makes it easy to work simultaneously with different projects requiring different versions of internal packages.&lt;br /&gt;
== Wrapper scripts for setting paths ==&lt;br /&gt;
&lt;br /&gt;
Nix has expressions for many of these that generate wrapper scripts that set path environment variables to bring a specific set of the internal packages into scope and then run the approriate program.&lt;br /&gt;
&lt;br /&gt;
The following Nix expression defines top-level myPython, myR, and myHaskell attributes that use the appropriate package-specific expressions to create wrappers for a selection of internal packages (for details about the Nix langauge see the [https://nixos.org/nix/manual/#ch-expression-language Nix Expression Language].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import &amp;amp;lt;nixpkgs&amp;amp;gt; { };&lt;br /&gt;
&lt;br /&gt;
rec {&lt;br /&gt;
  myPython = python3.buildEnv.override rec {&lt;br /&gt;
    extraLibs = with python3Packages; [ numpy scipy ];&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  myR = rWrapper.override rec {&lt;br /&gt;
    packages = with rPackages; [ rgeos rgdal ];&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  myHaskell = haskellPackages.ghcWithPackages (ghcpkgs:&lt;br /&gt;
    with ghcpkgs; [ pipes lens cabal-install ]&lt;br /&gt;
  );&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Saving it as ''~/.nix-defexpr/mypkgs.nix'' makes these available for installation with &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr mypkgs.myPython&lt;br /&gt;
cat $(which python3)&lt;br /&gt;
python3&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;import scipy&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+d&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
== Development environments ==&lt;br /&gt;
&lt;br /&gt;
A Nix expression evaluates to a specification for setting up a (build) environment and then doing a build in it. Frequently we want to do something very similar: setup a (development) environment and then do development in it.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-shell&amp;lt;/code&amp;gt; command bridges the gap between these two. It uses Nix to sets up a non-rooted (build) environment with the dependencies we specify and then laucnhes a (development) shell in it instead of a build process.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;mkdir devel&lt;br /&gt;
cd devel&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Say we need Clang and Python with the NumPy and SciPy packages. Instead of installing these into our global environment we can create a Nix expression that specifies these as build (development) inputs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import &amp;amp;lt;nixpkgs&amp;amp;gt; { };&lt;br /&gt;
&lt;br /&gt;
stdenv.mkDerivation {&lt;br /&gt;
  name = &amp;amp;quot;my-env&amp;amp;quot;;&lt;br /&gt;
  buildInputs = [&lt;br /&gt;
    ( python3.buildEnv.override rec {&lt;br /&gt;
        extraLibs = with python3Packages; [ numpy scipy ];&lt;br /&gt;
      } )&lt;br /&gt;
    clang&lt;br /&gt;
  ];&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
save it in ''default.nix'' and then run &amp;lt;code&amp;gt;nix-shell&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-shell&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Now we are in a build (development) environment with all the dependencies we specified in the appropriate PATHs.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;cat $(which python3)&lt;br /&gt;
clang --version&lt;br /&gt;
python3&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;import scipy&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+d&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
To return to our standard environment we just exit the shell. This is extreamily nice if we work on many projects with conflicting dependencies.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;exit&lt;br /&gt;
cd ..&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== One-off environments ==&lt;br /&gt;
&lt;br /&gt;
Quite frequently we need a one-off development environment with a few packages.  Say CLang and git.  Rather than have to write the following boilerplate ''default.nix'' file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import &amp;amp;lt;nixpkgs&amp;amp;gt; { };&lt;br /&gt;
&lt;br /&gt;
stdenv.mkDerivation {&lt;br /&gt;
  name = &amp;amp;quot;my-env&amp;amp;quot;;&lt;br /&gt;
  buildInputs = [&lt;br /&gt;
    clang&lt;br /&gt;
    git&lt;br /&gt;
  ];&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
we can just get &amp;lt;code&amp;gt;nix-shell&amp;lt;/code&amp;gt; to do it for us.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-shell --packages clang git&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+d&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Submitting Jobs =&lt;br /&gt;
&lt;br /&gt;
Loading the Nix module before submitting a job makes the Nix environment available to the job.  Note that these jobs will see the current Nix environment including any changes made after submission.  Compiled binaries should not require the Nix module to be loaded to run.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
sqsub ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
= Internals =&lt;br /&gt;
&lt;br /&gt;
This section details some of the internals of how Nix works and how to create your own packages.  It is more advanced material not required for the basic usage.&lt;br /&gt;
== The Nix store ==&lt;br /&gt;
&lt;br /&gt;
A Nix environment is just a collection of symlinks to all the packages that exist in that environment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;readlink $(which git)&lt;br /&gt;
readlink -f ~/.nix-profile&amp;lt;/pre&amp;gt;&lt;br /&gt;
Everything in Nix exists as a path in the Nix store. Each path is distinguished with a hash of either its contents or everything that went into creating it to keep it separate from everything else. Paths are immutable once created. This means they can be freely shared.&lt;br /&gt;
&lt;br /&gt;
Paths are created by the Nix build server when it realizes a Nix derivation. Nix derivations specify all the inputs to a jailed process that creates the contents of the store path.&lt;br /&gt;
== Nix expressions and instantiation ==&lt;br /&gt;
&lt;br /&gt;
Nix derivations are instantiated from Nix expressions, which are written in the Nix language. The &amp;lt;code&amp;gt;nix-repl&amp;lt;/code&amp;gt; program can be used to interactively experiment with the Nix language.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nix-repl&lt;br /&gt;
nix-repl&amp;lt;/pre&amp;gt;&lt;br /&gt;
The following ''cabextract.nix'' Nix expression evaluates to a derivation fully specifying how to build the &amp;lt;code&amp;gt;cabextract&amp;lt;/code&amp;gt; utility.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import ~/.nix-defexpr/nixpkgs { };&lt;br /&gt;
stdenv.mkDerivation rec {&lt;br /&gt;
  name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
  src = fetchurl {&lt;br /&gt;
    url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
    sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  meta = with stdenv.lib; {&lt;br /&gt;
    homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
    description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
    platforms = platforms.all;&lt;br /&gt;
    license = licenses.gpl3;&lt;br /&gt;
    maintainers = with maintainers; [ pSub ];&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is written using the &amp;lt;code&amp;gt;stdenv.mkDerivation&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;. This function creates a derivation that executes the standard unpack, patch, configure, build, check, install, fixup, check, and distribute steps on the package. It provides a series of hooks that can be used at each step to customize the process for non-standard packages.&lt;br /&gt;
&lt;br /&gt;
The Nix expression is instantiate to a derivation using &amp;lt;code&amp;gt;nix-instantiate&amp;lt;/code&amp;gt;. The leading ''./'' is required to distinguish that the arguments is file containing a Nix expression to be instantiated and not the name of a package in the default Nix expression to instantiate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabdrv=$(nix-instantiate ./cabextract.nix)&lt;br /&gt;
echo $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Nix derivations and realization ==&lt;br /&gt;
&lt;br /&gt;
The Nix derivation instantiated from the above Nix expression can be pretty-printed using the &amp;lt;code&amp;gt;pp-aterm&amp;lt;/code&amp;gt; program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nixpkgs.strategoPackages.strategoxt&lt;br /&gt;
pp-aterm -i $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;Derive(&lt;br /&gt;
  [(&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)]&lt;br /&gt;
, [ (&amp;amp;quot;/home/nixbld/store/...-stdenv.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  ]&lt;br /&gt;
, [&amp;amp;quot;/home/nixbld/store/...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, &amp;amp;quot;x86_64-linux&amp;amp;quot;&lt;br /&gt;
, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;&lt;br /&gt;
, [&amp;amp;quot;-e&amp;amp;quot;, &amp;amp;quot;...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, [ (&amp;amp;quot;buildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;builder&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;name&amp;amp;quot;, &amp;amp;quot;cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;nativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedNativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;src&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;stdenv&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-stdenv&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;system&amp;amp;quot;, &amp;amp;quot;x86_64-linux&amp;amp;quot;)&lt;br /&gt;
  ]&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The Nix build server realizes derivations by building the packages in an isolated environment. Each derivation specifies what comes out of the environment, what goes into it, the required machine architecture, what build program to execute in the environment, and what arguments and environment to pass to the program to be executed.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program &amp;lt;code&amp;gt;--realize&amp;lt;/code&amp;gt; option is used to signal the build server to realize the derivation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabpath=$(nix-store --realize $cabdrv)&lt;br /&gt;
echo $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; program will add the realized derivation to the users environment with the &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-i&amp;lt;/code&amp;gt;) option. Technically it creates a new realization of the &amp;lt;code&amp;gt;user-environment&amp;lt;/code&amp;gt; package that symlinks in the entire contents of the path path and switches to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The build log associated with a realization can be viewed with the &amp;lt;code&amp;gt;--read-log&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-l&amp;lt;/code&amp;gt;) option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --read-log $cabdrv&lt;br /&gt;
nix-store --read-log $cabpath&lt;br /&gt;
nix-store --read-log $(which git)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program also supports numerous other store related items such as computing the transitive closure of a package with the &amp;lt;code&amp;gt;--query&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-q&amp;lt;/code&amp;gt;) &amp;lt;code&amp;gt;--requisites&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-R&amp;lt;/code&amp;gt;) and exporting them via the &amp;lt;code&amp;gt;--export&amp;lt;/code&amp;gt; option to a Nix archive for import into another store.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --query --requisites $cabpath&lt;br /&gt;
nix-store --export $(nix-store --query --requisites $(which git)) | gzip &amp;amp;gt; git.nar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Nix default expression ==&lt;br /&gt;
&lt;br /&gt;
Nix has a default expression created from the contents of ''~/.nix-defexpr''. The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; operation normally works by selecting an attribute in this expression (fast) or matching against the &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; attribute in all the attributes in this expression (slow) to determine an expression to instantiate, realize, and then symlink into a new environment.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-channel&amp;lt;/code&amp;gt; command works by building new Nix expression packages (containing all the Nix expressions for the subscribed channels) and symlinking ''~/.nix-defexprs/channels'' to then. Adding additional expressions to ''~/.nix-defexpr'' makes them available for use with &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; as well. For example, the following ''~/.nix-defexpr/mypkgs'' expression packages up the above ''cabextract.nix'' example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;args@{ ... }: with import ./nixpkgs args;&lt;br /&gt;
rec {&lt;br /&gt;
  cabextract = stdenv.mkDerivation rec {&lt;br /&gt;
    name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    src = fetchurl {&lt;br /&gt;
      url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
      sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    meta = with stdenv.lib; {&lt;br /&gt;
      homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
      description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
      platforms = platforms.all;&lt;br /&gt;
      license = licenses.gpl3;&lt;br /&gt;
      maintainers = with maintainers; [ pSub ];&lt;br /&gt;
    };&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
This makes it possible to install packages from &amp;lt;code&amp;gt;mypkgs&amp;lt;/code&amp;gt; as easily as those from the official &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr mypkgs.cabextract&amp;lt;/pre&amp;gt;&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Nix Package Manager&amp;lt;br&amp;gt;&lt;br /&gt;
http://nixos.org/nix/&lt;br /&gt;
&lt;br /&gt;
o Official Nix/Nixpkgs/NixOS&amp;lt;br&amp;gt;&lt;br /&gt;
https://github.com/NixOS&lt;br /&gt;
&lt;br /&gt;
o Nix on SHARCNET (slides by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.sharcnet.ca/help/images/5/5f/Tyson_nix_2015.pdf&lt;br /&gt;
&lt;br /&gt;
o Exploring a new approach to package management (youtube video by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.youtube.com/watch?v=pQE9WTLAPHQ&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=13523</id>
		<title>NIX</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=13523"/>
				<updated>2016-04-14T20:42:57Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Merge in material prepared for TECC&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=NIX&lt;br /&gt;
|package_description=User Level Purely Functional Package Manager&lt;br /&gt;
|package_idnumber=171&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
Nix is an atomic pure non-mutable package manager system that allows users to manage their own software environment.  This environment is persistent and is shared across all clusters.&lt;br /&gt;
&lt;br /&gt;
* Users can build, install, upgrade, downgrade, and remove packages from their environment without root privileges and without affecting other users&lt;br /&gt;
* Operations are atomic, they either succeed and create a new environment or fail leaving the previous environment in place.  Previous environments can be switched back to at any point.&lt;br /&gt;
&lt;br /&gt;
The default Nix package set includes a huge selection (over 10,000) of recent versions of many packages.&lt;br /&gt;
== Enabling and disabling the Nix environment ==&lt;br /&gt;
&lt;br /&gt;
The user's current Nix environment is enabled by loading the nix module. This creates some ''.nix*'' files and sets some environment variables.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is disabled by unloading the nix module. This unsets the environment variables but leaves the ''.nix*'' files alone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module unload nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&lt;br /&gt;
module load nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
= Installing and remove packages =&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; command is used to setup your Nix environment.&lt;br /&gt;
== What do I have installed and what can I install ==&lt;br /&gt;
&lt;br /&gt;
Lets first see what we currently have installed.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Now let's see what is available. We request the attribute paths (unambiguous way of specifying a package) and the descriptions too (cursor to the right to see them). This takes a bit of time as it visits a lot of small files. Especially over NFS it can be a good idea to pipe it to a file and then grep that in the future.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query --available --attr-path --description&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Installing packages ==&lt;br /&gt;
&lt;br /&gt;
Let's say that we need a newer version of git than provided by default on our OS (e.g., the CentOS 6 one has issues with fetching over https). First lets check what our OS comes with.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git --version&lt;br /&gt;
which git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let's tell Nix to install its version in our environment.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr nixpkgs.git&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let's checkout what we have now (it may be necessary to tell bash to to forget remembered executable locations with &amp;lt;code&amp;gt;hash -r&amp;lt;/code&amp;gt; so it notices the new one).&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git --version&lt;br /&gt;
which git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Removing packages ==&lt;br /&gt;
&lt;br /&gt;
For completeness, lets add in the other usual version-control suspects.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr nixpkgs.subversion nixpkgs.mercurial&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Actually, we probably don't really want subversion any more. Let's remove that.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --uninstall subversion&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Environments =&lt;br /&gt;
&lt;br /&gt;
Nix keeps referring to user environments. Each time we install or remove packages we create a new environment based off of the previous environment.&lt;br /&gt;
== Switching between previous environments ==&lt;br /&gt;
&lt;br /&gt;
This means the previous environments still exist and we can switch back to them at any point. Let's say we changed our mind and want subversion back. It's trivial to restore the previous environment.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --rollback&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Of course we may want to do more than just move to the previous environment. We can get a list of all our environments so far and then jump directly to whatever one we want. Let's undo the rollback.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --list-generations&lt;br /&gt;
nix-env --switch-generation 4&lt;br /&gt;
nix-env --query&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Operations are atomic ==&lt;br /&gt;
&lt;br /&gt;
Due to the atomic property of Nix environments, we can't be left halfway through installing/updating packages. They either succeed and create us a new environment or leave us with the previous one intact.&lt;br /&gt;
&lt;br /&gt;
Let's go back to the start when we just had Nix itself and install the one true GNU distributed version control system tla. Don't let it complete though. Hit it with &amp;lt;code&amp;gt;CTRL+c&amp;lt;/code&amp;gt; partway through.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --switch-generation 1&lt;br /&gt;
nix-env --install --attr nixpkgs.tla&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+c&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Nothing bad happens. The operation didn't complete so it has no effect on the environment whatsoever.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query&lt;br /&gt;
nix-env --list-generations&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Nix only does things once ==&lt;br /&gt;
&lt;br /&gt;
The install and remove commands take the current environment and create a new environment with the changes. This works regardless of which environment we are currently in. Let's create a new environment from our original environment by just adding git and mercurial.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --list-generations&lt;br /&gt;
nix-env --install nixpkgs.git nixpkgs.mercurial&lt;br /&gt;
nix-env --list-generations&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Notice how much much faster it was to install git and mercurial the second time? That is because the software already existed in the local Nix store from the previous installs so Nix just reused it.&lt;br /&gt;
== Garbage collection ==&lt;br /&gt;
&lt;br /&gt;
Nix periodically goes through and removes any software not accessible from any existing environments. This means we have to explicitly delete environments we don't want anymore so Nix is able to reclaim the space. We can delete specific environments or any sufficiently old.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --delete-generations 30d&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Using channels to obtain Nix expressions =&lt;br /&gt;
&lt;br /&gt;
Nix packages are Nix expressions that specify how to build something. The default source for of these expression for &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; is ''~/.nix-defexp'' and ''~/.nix-defexp/channels''. Nix channels provide a way to populate this later directory with existing expressions from repositories on the internet.&lt;br /&gt;
== Subscribing to a channel ==&lt;br /&gt;
&lt;br /&gt;
By default we are subscribed to the SHARCNET version of the latest NixOS release under the name nixpkg. Let us add the older NixOS 15.09 release too under the name nixpkgs_old and then download the latest versions of all NixOS 15.09 the expressions.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-channel --list&lt;br /&gt;
nix-channel --add file:///nix/channels/sharcnet-15.09 nixpkgs_old&lt;br /&gt;
nix-channel --list&lt;br /&gt;
nix-channel --update nixpkgs_old&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Installing packages from a channel ==&lt;br /&gt;
&lt;br /&gt;
Now searching our available packages we see that we can install software using either the nixpkgs or nixpkgs_old expressions.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --query --available --attr-path --description git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let's replace our git built and installed from the unstable (nixpkgs) expression with one built and installed from the stable expression (note that git is the default version of git which is gitMinimal).&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr nixpkgs_old.git&lt;br /&gt;
nix-env --query&lt;br /&gt;
git --version&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== What about dependency conflicts ==&lt;br /&gt;
&lt;br /&gt;
There are no issues with having a mix of packages installed from different sources even if they have conflicting dependencies. Nix puts each package in a separate directory under ''/nix/store'' versioned by the hash of the its build instructions. Binaries are linked with rpaths to ensure they always find the versions they need.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ldd $(readlink ($which git))&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Switching between environments continue to work as before.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --rollback&lt;br /&gt;
git --version&lt;br /&gt;
nix-env --list-generations&lt;br /&gt;
nix-env --switch-generation 5&lt;br /&gt;
git --version&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Switching between previous updates ==&lt;br /&gt;
&lt;br /&gt;
The channel updates (updating the list of expressions we can build and install from) are also atomic and versioned. This ensures we never find ourselves stuck due to accidentally updating to something broken.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-channel --rollback&lt;br /&gt;
nix-env --query --available --attr-path git&lt;br /&gt;
nix-channel --rollback 2&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Development with Nix (e.g., Python, R, etc.) =&lt;br /&gt;
&lt;br /&gt;
Several languages have their own repository of packages and associated infrastructure (e.g., PyPI and pip). Nix builds on these to automatically handle the external dependencies (e.g., C libraries) and makes it easy to work simultaneously with different projects requiring different versions of internal packages.&lt;br /&gt;
== Wrapper scripts for setting paths ==&lt;br /&gt;
&lt;br /&gt;
Nix has expressions for many of these that generate wrapper scripts that set path environment variables to bring a specific set of the internal packages into scope and then run the approriate program.&lt;br /&gt;
&lt;br /&gt;
The following Nix expression defines top-level myPython, myR, and myHaskell attributes that use the appropriate package-specific expressions to create wrappers for a selection of internal packages (for details about the Nix langauge see the [https://nixos.org/nix/manual/#ch-expression-language Nix Expression Language].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import &amp;amp;lt;nixpkgs&amp;amp;gt; { };&lt;br /&gt;
&lt;br /&gt;
rec {&lt;br /&gt;
  myPython = python3.buildEnv.override rec {&lt;br /&gt;
    extraLibs = with python3Packages; [ numpy scipy ];&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  myR = rWrapper.override rec {&lt;br /&gt;
    packages = with rPackages; [ rgeos rgdal ];&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  myHaskell = haskellPackages.ghcWithPackages (ghcpkgs:&lt;br /&gt;
    with ghcpkgs; [ pipes lens cabal-install ]&lt;br /&gt;
  );&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Saving it as ''~/.nix-defexpr/mypkgs.nix'' makes these available for installation with &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-env --install --attr mypkgs.myPython&lt;br /&gt;
cat $(which python3)&lt;br /&gt;
python3&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;import scipy&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+d&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
== Development environments ==&lt;br /&gt;
&lt;br /&gt;
A Nix expression evaluates to a specification for setting up a (build) environment and then doing a build in it. Frequently we want to do something very similar: setup a (development) environment and then do development in it.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-shell&amp;lt;/code&amp;gt; command bridges the gap between these two. It uses Nix to sets up a non-rooted (build) environment with the dependencies we specify and then laucnhes a (development) shell in it instead of a build process.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;mkdir devel&lt;br /&gt;
cd devel&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Say we need Clang and Python with the NumPy and SciPy packages. Instead of installing these into our global environment we can create a Nix expression that specifies these as build (development) inputs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import &amp;amp;lt;nixpkgs&amp;amp;gt; { };&lt;br /&gt;
&lt;br /&gt;
stdenv.mkDerivation {&lt;br /&gt;
  name = &amp;amp;quot;my-env&amp;amp;quot;;&lt;br /&gt;
  buildInputs = [&lt;br /&gt;
    ( python3.buildEnv.override rec {&lt;br /&gt;
        extraLibs = with python3Packages; [ numpy scipy ];&lt;br /&gt;
      } )&lt;br /&gt;
    clang&lt;br /&gt;
  ];&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
save it in ''default.nix'' and then run &amp;lt;code&amp;gt;nix-shell&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;nix-shell&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Now we are in a build (development) environment with all the dependencies we specified in the appropriate PATHs.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;cat $(which python3)&lt;br /&gt;
clang --version&lt;br /&gt;
python3&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;import scipy&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;CTRL+d&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
To return to our standard environment we just exit the shell. This is extreamily nice if we work on many projects with conflicting dependencies.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;exit&lt;br /&gt;
cd ..&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
= Submitting Jobs =&lt;br /&gt;
&lt;br /&gt;
Loading the Nix module before submitting a job makes the Nix environment available to the job.  Note that these jobs will see the current Nix environment including any changes made after submission.  Compiled binaries should not require the Nix module to be loaded to run.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
sqsub ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
= Internals =&lt;br /&gt;
&lt;br /&gt;
This section details some of the internals of how Nix works and how to create your own packages.  It is more advanced material not required for the basic usage.&lt;br /&gt;
== The Nix store ==&lt;br /&gt;
&lt;br /&gt;
A Nix environment is just a collection of symlinks to all the packages that exist in that environment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;readlink $(which git)&lt;br /&gt;
readlink -f ~/.nix-profile&amp;lt;/pre&amp;gt;&lt;br /&gt;
Everything in Nix exists as a path in the Nix store. Each path is distinguished with a hash of either its contents or everything that went into creating it to keep it separate from everything else. Paths are immutable once created. This means they can be freely shared.&lt;br /&gt;
&lt;br /&gt;
Paths are created by the Nix build server when it realizes a Nix derivation. Nix derivations specify all the inputs to a jailed process that creates the contents of the store path.&lt;br /&gt;
== Nix expressions and instantiation ==&lt;br /&gt;
&lt;br /&gt;
Nix derivations are instantiated from Nix expressions, which are written in the Nix language. The &amp;lt;code&amp;gt;nix-repl&amp;lt;/code&amp;gt; program can be used to interactively experiment with the Nix language.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nix-repl&lt;br /&gt;
nix-repl&amp;lt;/pre&amp;gt;&lt;br /&gt;
The following ''cabextract.nix'' Nix expression evaluates to a derivation fully specifying how to build the &amp;lt;code&amp;gt;cabextract&amp;lt;/code&amp;gt; utility.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import ~/.nix-defexpr/nixpkgs { };&lt;br /&gt;
stdenv.mkDerivation rec {&lt;br /&gt;
  name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
  src = fetchurl {&lt;br /&gt;
    url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
    sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  meta = with stdenv.lib; {&lt;br /&gt;
    homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
    description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
    platforms = platforms.all;&lt;br /&gt;
    license = licenses.gpl3;&lt;br /&gt;
    maintainers = with maintainers; [ pSub ];&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is written using the &amp;lt;code&amp;gt;stdenv.mkDerivation&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;. This function creates a derivation that executes the standard unpack, patch, configure, build, check, install, fixup, check, and distribute steps on the package. It provides a series of hooks that can be used at each step to customize the process for non-standard packages.&lt;br /&gt;
&lt;br /&gt;
The Nix expression is instantiate to a derivation using &amp;lt;code&amp;gt;nix-instantiate&amp;lt;/code&amp;gt;. The leading ''./'' is required to distinguish that the arguments is file containing a Nix expression to be instantiated and not the name of a package in the default Nix expression to instantiate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabdrv=$(nix-instantiate ./cabextract.nix)&lt;br /&gt;
echo $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Nix derivations and realization ==&lt;br /&gt;
&lt;br /&gt;
The Nix derivation instantiated from the above Nix expression can be pretty-printed using the &amp;lt;code&amp;gt;pp-aterm&amp;lt;/code&amp;gt; program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nixpkgs.strategoPackages.strategoxt&lt;br /&gt;
pp-aterm -i $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;Derive(&lt;br /&gt;
  [(&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)]&lt;br /&gt;
, [ (&amp;amp;quot;/home/nixbld/store/...-stdenv.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  ]&lt;br /&gt;
, [&amp;amp;quot;/home/nixbld/store/...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, &amp;amp;quot;x86_64-linux&amp;amp;quot;&lt;br /&gt;
, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;&lt;br /&gt;
, [&amp;amp;quot;-e&amp;amp;quot;, &amp;amp;quot;...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, [ (&amp;amp;quot;buildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;builder&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;name&amp;amp;quot;, &amp;amp;quot;cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;nativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedNativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;src&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;stdenv&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-stdenv&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;system&amp;amp;quot;, &amp;amp;quot;x86_64-linux&amp;amp;quot;)&lt;br /&gt;
  ]&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The Nix build server realizes derivations by building the packages in an isolated environment. Each derivation specifies what comes out of the environment, what goes into it, the required machine architecture, what build program to execute in the environment, and what arguments and environment to pass to the program to be executed.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program &amp;lt;code&amp;gt;--realize&amp;lt;/code&amp;gt; option is used to signal the build server to realize the derivation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabpath=$(nix-store --realize $cabdrv)&lt;br /&gt;
echo $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; program will add the realized derivation to the users environment with the &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-i&amp;lt;/code&amp;gt;) option. Technically it creates a new realization of the &amp;lt;code&amp;gt;user-environment&amp;lt;/code&amp;gt; package that symlinks in the entire contents of the path path and switches to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The build log associated with a realization can be viewed with the &amp;lt;code&amp;gt;--read-log&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-l&amp;lt;/code&amp;gt;) option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --read-log $cabdrv&lt;br /&gt;
nix-store --read-log $cabpath&lt;br /&gt;
nix-store --read-log $(which git)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program also supports numerous other store related items such as computing the transitive closure of a package with the &amp;lt;code&amp;gt;--query&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-q&amp;lt;/code&amp;gt;) &amp;lt;code&amp;gt;--requisites&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-R&amp;lt;/code&amp;gt;) and exporting them via the &amp;lt;code&amp;gt;--export&amp;lt;/code&amp;gt; option to a Nix archive for import into another store.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --query --requisites $cabpath&lt;br /&gt;
nix-store --export $(nix-store --query --requisites $(which git)) | gzip &amp;amp;gt; git.nar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Nix default expression ==&lt;br /&gt;
&lt;br /&gt;
Nix has a default expression created from the contents of ''~/.nix-defexpr''. The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; operation normally works by selecting an attribute in this expression (fast) or matching against the &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; attribute in all the attributes in this expression (slow) to determine an expression to instantiate, realize, and then symlink into a new environment.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-channel&amp;lt;/code&amp;gt; command works by building new Nix expression packages (containing all the Nix expressions for the subscribed channels) and symlinking ''~/.nix-defexprs/channels'' to then. Adding additional expressions to ''~/.nix-defexpr'' makes them available for use with &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; as well. For example, the following ''~/.nix-defexpr/mypkgs'' expression packages up the above ''cabextract.nix'' example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;args@{ ... }: with import ./nixpkgs args;&lt;br /&gt;
rec {&lt;br /&gt;
  cabextract = stdenv.mkDerivation rec {&lt;br /&gt;
    name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    src = fetchurl {&lt;br /&gt;
      url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
      sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    meta = with stdenv.lib; {&lt;br /&gt;
      homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
      description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
      platforms = platforms.all;&lt;br /&gt;
      license = licenses.gpl3;&lt;br /&gt;
      maintainers = with maintainers; [ pSub ];&lt;br /&gt;
    };&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
This makes it possible to install packages from &amp;lt;code&amp;gt;mypkgs&amp;lt;/code&amp;gt; as easily as those from the official &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr mypkgs.cabextract&amp;lt;/pre&amp;gt;&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Nix Package Manager&amp;lt;br&amp;gt;&lt;br /&gt;
http://nixos.org/nix/&lt;br /&gt;
&lt;br /&gt;
o Official Nix/Nixpkgs/NixOS&amp;lt;br&amp;gt;&lt;br /&gt;
https://github.com/NixOS&lt;br /&gt;
&lt;br /&gt;
o Nix on SHARCNET (slides by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.sharcnet.ca/help/images/5/5f/Tyson_nix_2015.pdf&lt;br /&gt;
&lt;br /&gt;
o Exploring a new approach to package management (youtube video by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.youtube.com/watch?v=pQE9WTLAPHQ&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=12562</id>
		<title>NIX</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=12562"/>
				<updated>2015-12-14T21:29:36Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Correct formating on file names&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=NIX&lt;br /&gt;
|package_description=User Level Purely Functional Package Manager&lt;br /&gt;
|package_idnumber=171&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
Nix is an atomic pure non-mutable package manager system that allows users to manage their own software environment.  This environment is persistent and is shared across all clusters.&lt;br /&gt;
&lt;br /&gt;
* Users can build, install, upgrade, downgrade, and remove packages from their environment without root privileges and without affecting other users&lt;br /&gt;
* Operations are atomic, they either succeed and create a new environment or fail leaving the previous environment in place.  Previous environments can be switched back to at any point.&lt;br /&gt;
&lt;br /&gt;
The default Nix package set includes a huge selection (over 10,000) of recent versions of many packages.&lt;br /&gt;
&lt;br /&gt;
=Version Selection=&lt;br /&gt;
&lt;br /&gt;
This section details how to enable your Nix environment and install and remove packages from it.  See the [[#General Notes|General Notes]] section for a more advanced discussion of how Nix works and how to create your own packages.&lt;br /&gt;
&lt;br /&gt;
== Enabling and disabling the Nix environment ==&lt;br /&gt;
&lt;br /&gt;
The user's current Nix environment is enabled by loading the nix module. This creates some ''.nix*'' files and sets some environment variables.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is disabled by unloading the nix module. This unsets the environment variables but leaves the ''.nix*'' files alone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module unload nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&lt;br /&gt;
module load nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing, upgrading, uninstalling, and querying software ==&lt;br /&gt;
&lt;br /&gt;
The nix environment is manipulated via the &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; command. The &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-i&amp;lt;/code&amp;gt;) option is used to install software&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;git --version&lt;br /&gt;
which git&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install git&lt;br /&gt;
git --version&lt;br /&gt;
which git&amp;lt;/pre&amp;gt;&lt;br /&gt;
This takes a long time as it has to open many many files to enumerate all available software to locate the requested one by name. A faster way is to directly specify what to install by the attribute instead using the &amp;lt;code&amp;gt;--attr&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-a&amp;lt;/code&amp;gt;) option&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nixpkgs.subversion nixpkgs.mercurial&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;--upgrade&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-u&amp;lt;/code&amp;gt;) option upgrades installed software to the latest version. The &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-i&amp;lt;/code&amp;gt;) option can also be used for this purpose.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --upgrade --attr nixpkgs.git&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;--uninstall&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-e&amp;lt;/code&amp;gt;) option uninstalls software. It can be done by name or path.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --uninstall $(which svn)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The contents of the environment is queried via the &amp;lt;code&amp;gt;--query&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-q&amp;lt;/code&amp;gt;) option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --query&amp;lt;/pre&amp;gt;&lt;br /&gt;
All possible packages can be queried via the &amp;lt;code&amp;gt;--available&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-a&amp;lt;/code&amp;gt;) option. This is quite slow again due to having to enumerate all available software. Adding &amp;lt;code&amp;gt;--attr-path&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-P&amp;lt;/code&amp;gt;) includes the faster attribute paths and &amp;lt;code&amp;gt;--description&amp;lt;/code&amp;gt; includes the descriptions. It is a good idea to save this to a file for future reference.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --query --available --description --attr-path &amp;amp;gt; nix-packages.txt&lt;br /&gt;
grep git nix-packages.txt | less -S&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Environment transactions ==&lt;br /&gt;
&lt;br /&gt;
Environments are non-mutable. All &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; commands do not actually modify the current environment. Rather they create a new environment based on the existing environment and switch to it. This means all previous environments continue to exist and can be re-activated.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;--rollback&amp;lt;/code&amp;gt; option can be used to restore the previous environment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --query&lt;br /&gt;
nix-env --rollback&lt;br /&gt;
nix-env --query&amp;lt;/pre&amp;gt;&lt;br /&gt;
Previous generations of the environment can be displayed with the &amp;lt;code&amp;gt;--list-generations&amp;lt;/code&amp;gt; option and any one can be switched to with the &amp;lt;code&amp;gt;--switch-generation&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --list-generations&lt;br /&gt;
nix-env --switch-generation 3&lt;br /&gt;
nix-env --query&amp;lt;/pre&amp;gt;&lt;br /&gt;
Nix preserves any software this is accessible for any user environment. This means it is important to periodically delete older environment generations so Nix can remove the software associated with them. This is done with the &amp;lt;code&amp;gt;--delete-generations&amp;lt;/code&amp;gt; options.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --delete-generations 30d&amp;lt;/pre&amp;gt;&lt;br /&gt;
Environments are technically realizations of the Nix user-environment package.&lt;br /&gt;
&lt;br /&gt;
=Job Submission=&lt;br /&gt;
&lt;br /&gt;
Loading the Nix module before submitting a job makes the Nix environment available to the job.  Note that these jobs will see the current Nix environment including any changes made after submission.  Compiled binaries should not require the Nix module to be loaded to run.&lt;br /&gt;
&lt;br /&gt;
=Example Job=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
sqsub ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= General Notes =&lt;br /&gt;
&lt;br /&gt;
This section details some of the internals of how Nix works and how to create your own packages.  It is more advanced material not required for the basic usage detailed under the [[#Version Selection|Version Selection]] section above.&lt;br /&gt;
&lt;br /&gt;
== The Nix store ==&lt;br /&gt;
&lt;br /&gt;
A Nix environment is just a collection of symlinks to all the packages that exist in that environment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;readlink $(which git)&lt;br /&gt;
readlink -f ~/.nix-profile&amp;lt;/pre&amp;gt;&lt;br /&gt;
Everything in Nix exists as a path in the Nix store. Each path is distinguished with a hash of either its contents or everything that went into creating it to keep it separate from everything else. Paths are immutable once created. This means they can be freely shared.&lt;br /&gt;
&lt;br /&gt;
Paths are created by the Nix build server when it realizes a Nix derivation. Nix derivations specify all the inputs to a jailed process that creates the contents of the store path.&lt;br /&gt;
&lt;br /&gt;
== Nix expressions and instantiation ==&lt;br /&gt;
&lt;br /&gt;
Nix derivations are instantiated from Nix expressions, which are written in the Nix language. The &amp;lt;code&amp;gt;nix-repl&amp;lt;/code&amp;gt; program can be used to interactively experiment with the Nix language.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nix-repl&lt;br /&gt;
nix-repl&amp;lt;/pre&amp;gt;&lt;br /&gt;
The following ''cabextract.nix'' Nix expression evaluates to a derivation fully specifying how to build the &amp;lt;code&amp;gt;cabextract&amp;lt;/code&amp;gt; utility.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import ~/.nix-defexpr/nixpkgs { };&lt;br /&gt;
stdenv.mkDerivation rec {&lt;br /&gt;
  name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
  src = fetchurl {&lt;br /&gt;
    url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
    sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  meta = with stdenv.lib; {&lt;br /&gt;
    homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
    description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
    platforms = platforms.all;&lt;br /&gt;
    license = licenses.gpl3;&lt;br /&gt;
    maintainers = with maintainers; [ pSub ];&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is written using the &amp;lt;code&amp;gt;stdenv.mkDerivation&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;. This function creates a derivation that executes the standard unpack, patch, configure, build, check, install, fixup, check, and distribute steps on the package. It provides a series of hooks that can be used at each step to customize the process for non-standard packages.&lt;br /&gt;
&lt;br /&gt;
The Nix expression is instantiate to a derivation using &amp;lt;code&amp;gt;nix-instantiate&amp;lt;/code&amp;gt;. The leading ''./'' is required to distinguish that the arguments is file containing a Nix expression to be instantiated and not the name of a package in the default Nix expression to instantiate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabdrv=$(nix-instantiate ./cabextract.nix)&lt;br /&gt;
echo $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nix derivations and realization ==&lt;br /&gt;
&lt;br /&gt;
The Nix derivation instantiated from the above Nix expression can be pretty-printed using the &amp;lt;code&amp;gt;pp-aterm&amp;lt;/code&amp;gt; program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nixpkgs.strategoPackages.strategoxt&lt;br /&gt;
pp-aterm -i $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;Derive(&lt;br /&gt;
  [(&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)]&lt;br /&gt;
, [ (&amp;amp;quot;/home/nixbld/store/...-stdenv.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  ]&lt;br /&gt;
, [&amp;amp;quot;/home/nixbld/store/...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, &amp;amp;quot;x86_64-linux&amp;amp;quot;&lt;br /&gt;
, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;&lt;br /&gt;
, [&amp;amp;quot;-e&amp;amp;quot;, &amp;amp;quot;...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, [ (&amp;amp;quot;buildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;builder&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;name&amp;amp;quot;, &amp;amp;quot;cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;nativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedNativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;src&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;stdenv&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-stdenv&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;system&amp;amp;quot;, &amp;amp;quot;x86_64-linux&amp;amp;quot;)&lt;br /&gt;
  ]&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The Nix build server realizes derivations by building the packages in an isolated environment. Each derivation specifies what comes out of the environment, what goes into it, the required machine architecture, what build program to execute in the environment, and what arguments and environment to pass to the program to be executed.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program &amp;lt;code&amp;gt;--realize&amp;lt;/code&amp;gt; option is used to signal the build server to realize the derivation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabpath=$(nix-store --realize $cabdrv)&lt;br /&gt;
echo $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; program will add the realized derivation to the users environment with the &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-i&amp;lt;/code&amp;gt;) option. Technically it creates a new realization of the &amp;lt;code&amp;gt;user-environment&amp;lt;/code&amp;gt; package that symlinks in the entire contents of the path path and switches to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The build log associated with a realization can be viewed with the &amp;lt;code&amp;gt;--read-log&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-l&amp;lt;/code&amp;gt;) option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --read-log $cabdrv&lt;br /&gt;
nix-store --read-log $cabpath&lt;br /&gt;
nix-store --read-log $(which git)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program also supports numerous other store related items such as computing the transitive closure of a package with the &amp;lt;code&amp;gt;--query&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-q&amp;lt;/code&amp;gt;) &amp;lt;code&amp;gt;--requisites&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-R&amp;lt;/code&amp;gt;) and exporting them via the &amp;lt;code&amp;gt;--export&amp;lt;/code&amp;gt; option to a Nix archive for import into another store.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --query --requisites $cabpath&lt;br /&gt;
nix-store --export $(nix-store --query --requisites $(which git)) | gzip &amp;amp;gt; git.nar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nix default expression ==&lt;br /&gt;
&lt;br /&gt;
Nix has a default expression created from the contents of ''~/.nix-defexpr''. The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; operation normally works by selecting an attribute in this expression (fast) or matching against the &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; attribute in all the attributes in this expression (slow) to determine an expression to instantiate, realize, and then symlink into a new environment.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix&amp;lt;/code&amp;gt; module sets up a default ''~/.nix-defexpr/nixpkgs'' that symlinks to a slightly modified version of the official Nix ''nixpkgs''. This can be entirely replace this or augment. For example, the following ''~/.nix-defexpr/mypkgs'' expression packages up the above ''cabextract.nix'' example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;args@{ ... }: with import ./nixpkgs args;&lt;br /&gt;
rec {&lt;br /&gt;
  cabextract = stdenv.mkDerivation rec {&lt;br /&gt;
    name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    src = fetchurl {&lt;br /&gt;
      url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
      sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    meta = with stdenv.lib; {&lt;br /&gt;
      homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
      description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
      platforms = platforms.all;&lt;br /&gt;
      license = licenses.gpl3;&lt;br /&gt;
      maintainers = with maintainers; [ pSub ];&lt;br /&gt;
    };&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
This makes it possible to install packages from &amp;lt;code&amp;gt;mypkgs&amp;lt;/code&amp;gt; as easily as those from the official &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr mypkgs.cabextract&amp;lt;/pre&amp;gt;&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Nix Package Manager&amp;lt;br&amp;gt;&lt;br /&gt;
http://nixos.org/nix/&lt;br /&gt;
&lt;br /&gt;
o Official Nix/Nixpkgs/NixOS&amp;lt;br&amp;gt;&lt;br /&gt;
https://github.com/NixOS&lt;br /&gt;
&lt;br /&gt;
o Nix on SHARCNET (slides by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.sharcnet.ca/help/images/5/5f/Tyson_nix_2015.pdf&lt;br /&gt;
&lt;br /&gt;
o Exploring a new approach to package management (youtube video by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.youtube.com/watch?v=pQE9WTLAPHQ&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=12551</id>
		<title>NIX</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=12551"/>
				<updated>2015-12-10T22:03:21Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Clean up in page links a bit&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=NIX&lt;br /&gt;
|package_description=User Level Purely Functional Package Manager&lt;br /&gt;
|package_idnumber=171&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
Nix is an atomic pure non-mutable package manager system that allows users to manage their own software environment.  This environment is persistent and is shared across all clusters.&lt;br /&gt;
&lt;br /&gt;
* Users can build, install, upgrade, downgrade, and remove packages from their environment without root privileges and without affecting other users&lt;br /&gt;
* Operations are atomic, they either succeed and create a new environment or fail leaving the previous environment in place.  Previous environments can be switched back to at any point.&lt;br /&gt;
&lt;br /&gt;
The default Nix package set includes a huge selection (over 10,000) of recent versions of many packages.&lt;br /&gt;
&lt;br /&gt;
=Version Selection=&lt;br /&gt;
&lt;br /&gt;
This section details how to enable your Nix environment and install and remove packages from it.  See the [[#General Notes|General Notes]] section for a more advanced discussion of how Nix works and how to create your own packages.&lt;br /&gt;
&lt;br /&gt;
== Enabling and disabling the Nix environment ==&lt;br /&gt;
&lt;br /&gt;
The user's current Nix environment is enabled by loading the nix module. This creates some *.nix&amp;amp;amp* files and sets some environment variables.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is disabled by unloading the nix module. This unsets the environment variables but leaves the *.nix** files alone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module unload nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&lt;br /&gt;
module load nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing, upgrading, uninstalling, and querying software ==&lt;br /&gt;
&lt;br /&gt;
The nix environment is manipulated via the &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; command. The &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-i&amp;lt;/code&amp;gt;) option is used to install software&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;git --version&lt;br /&gt;
which git&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install git&lt;br /&gt;
git --version&lt;br /&gt;
which git&amp;lt;/pre&amp;gt;&lt;br /&gt;
This takes a long time as it has to open many many files to enumerate all available software to locate the requested one by name. A faster way is to directly specify what to install by the attribute instead using the &amp;lt;code&amp;gt;--attr&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-a&amp;lt;/code&amp;gt;) option&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nixpkgs.subversion nixpkgs.mercurial&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;--upgrade&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-u&amp;lt;/code&amp;gt;) option upgrades installed software to the latest version. The &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-i&amp;lt;/code&amp;gt;) option can also be used for this purpose.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --upgrade --attr nixpkgs.git&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;--uninstall&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-e&amp;lt;/code&amp;gt;) option uninstalls software. It can be done by name or path.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --uninstall $(which svn)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The contents of the environment is queried via the &amp;lt;code&amp;gt;--query&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-q&amp;lt;/code&amp;gt;) option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --query&amp;lt;/pre&amp;gt;&lt;br /&gt;
All possible packages can be queried via the &amp;lt;code&amp;gt;--available&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-a&amp;lt;/code&amp;gt;) option. This is quite slow again due to having to enumerate all available software. Adding &amp;lt;code&amp;gt;--attr-path&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-P&amp;lt;/code&amp;gt;) includes the faster attribute paths and &amp;lt;code&amp;gt;--description&amp;lt;/code&amp;gt; includes the descriptions. It is a good idea to save this to a file for future reference.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --query --available --description --attr-path &amp;amp;gt; nix-packages.txt&lt;br /&gt;
grep git nix-packages.txt | less -S&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Environment transactions ==&lt;br /&gt;
&lt;br /&gt;
Environments are non-mutable. All &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; commands do not actually modify the current environment. Rather they create a new environment based on the existing environment and switch to it. This means all previous environments continue to exist and can be re-activated.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;--rollback&amp;lt;/code&amp;gt; option can be used to restore the previous environment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --query&lt;br /&gt;
nix-env --rollback&lt;br /&gt;
nix-env --query&amp;lt;/pre&amp;gt;&lt;br /&gt;
Previous generations of the environment can be displayed with the &amp;lt;code&amp;gt;--list-generations&amp;lt;/code&amp;gt; option and any one can be switched to with the &amp;lt;code&amp;gt;--switch-generation&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --list-generations&lt;br /&gt;
nix-env --switch-generation 3&lt;br /&gt;
nix-env --query&amp;lt;/pre&amp;gt;&lt;br /&gt;
Nix preserves any software this is accessible for any user environment. This means it is important to periodically delete older environment generations so Nix can remove the software associated with them. This is done with the &amp;lt;code&amp;gt;--delete-generations&amp;lt;/code&amp;gt; options.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --delete-generations 30d&amp;lt;/pre&amp;gt;&lt;br /&gt;
Environments are technically realizations of the Nix user-environment package.&lt;br /&gt;
&lt;br /&gt;
=Job Submission=&lt;br /&gt;
&lt;br /&gt;
Loading the Nix module before submitting a job makes the Nix environment available to the job.  Note that these jobs will see the current Nix environment including any changes made after submission.  Compiled binaries should not require the Nix module to be loaded to run.&lt;br /&gt;
&lt;br /&gt;
=Example Job=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
sqsub ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= General Notes =&lt;br /&gt;
&lt;br /&gt;
This section details some of the internals of how Nix works and how to create your own packages.  It is more advanced material not required for the basic usage detailed under the [[#Version Selection|Version Selection]] section above.&lt;br /&gt;
&lt;br /&gt;
== The Nix store ==&lt;br /&gt;
&lt;br /&gt;
A Nix environment is just a collection of symlinks to all the packages that exist in that environment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;readlink $(which git)&lt;br /&gt;
readlink -f ~/.nix-profile&amp;lt;/pre&amp;gt;&lt;br /&gt;
Everything in Nix exists as a path in the Nix store. Each path is distinguished with a hash of either its contents or everything that went into creating it to keep it separate from everything else. Paths are immutable once created. This means they can be freely shared.&lt;br /&gt;
&lt;br /&gt;
Paths are created by the Nix build server when it realizes a Nix derivation. Nix derivations specify all the inputs to a jailed process that creates the contents of the store path.&lt;br /&gt;
&lt;br /&gt;
== Nix expressions and instantiation ==&lt;br /&gt;
&lt;br /&gt;
Nix derivations are instantiated from Nix expressions, which are written in the Nix language. The &amp;lt;code&amp;gt;nix-repl&amp;lt;/code&amp;gt; program can be used to interactively experiment with the Nix language.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nix-repl&lt;br /&gt;
nix-repl&amp;lt;/pre&amp;gt;&lt;br /&gt;
The following ''cabextract.nix'' Nix expression evaluates to a derivation fully specifying how to build the &amp;lt;code&amp;gt;cabextract&amp;lt;/code&amp;gt; utility.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import ~/.nix-defexpr/nixpkgs { };&lt;br /&gt;
stdenv.mkDerivation rec {&lt;br /&gt;
  name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
  src = fetchurl {&lt;br /&gt;
    url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
    sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  meta = with stdenv.lib; {&lt;br /&gt;
    homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
    description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
    platforms = platforms.all;&lt;br /&gt;
    license = licenses.gpl3;&lt;br /&gt;
    maintainers = with maintainers; [ pSub ];&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is written using the &amp;lt;code&amp;gt;stdenv.mkDerivation&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;. This function creates a derivation that executes the standard unpack, patch, configure, build, check, install, fixup, check, and distribute steps on the package. It provides a series of hooks that can be used at each step to customize the process for non-standard packages.&lt;br /&gt;
&lt;br /&gt;
The Nix expression is instantiate to a derivation using &amp;lt;code&amp;gt;nix-instantiate&amp;lt;/code&amp;gt;. The leading ''./'' is required to distinguish that the arguments is file containing a Nix expression to be instantiated and not the name of a package in the default Nix expression to instantiate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabdrv=$(nix-instantiate ./cabextract.nix)&lt;br /&gt;
echo $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nix derivations and realization ==&lt;br /&gt;
&lt;br /&gt;
The Nix derivation instantiated from the above Nix expression can be pretty-printed using the &amp;lt;code&amp;gt;pp-aterm&amp;lt;/code&amp;gt; program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nixpkgs.strategoPackages.strategoxt&lt;br /&gt;
pp-aterm -i $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;Derive(&lt;br /&gt;
  [(&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)]&lt;br /&gt;
, [ (&amp;amp;quot;/home/nixbld/store/...-stdenv.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  ]&lt;br /&gt;
, [&amp;amp;quot;/home/nixbld/store/...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, &amp;amp;quot;x86_64-linux&amp;amp;quot;&lt;br /&gt;
, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;&lt;br /&gt;
, [&amp;amp;quot;-e&amp;amp;quot;, &amp;amp;quot;...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, [ (&amp;amp;quot;buildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;builder&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;name&amp;amp;quot;, &amp;amp;quot;cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;nativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedNativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;src&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;stdenv&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-stdenv&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;system&amp;amp;quot;, &amp;amp;quot;x86_64-linux&amp;amp;quot;)&lt;br /&gt;
  ]&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The Nix build server realizes derivations by building the packages in an isolated environment. Each derivation specifies what comes out of the environment, what goes into it, the required machine architecture, what build program to execute in the environment, and what arguments and environment to pass to the program to be executed.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program &amp;lt;code&amp;gt;--realize&amp;lt;/code&amp;gt; option is used to signal the build server to realize the derivation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabpath=$(nix-store --realize $cabdrv)&lt;br /&gt;
echo $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; program will add the realized derivation to the users environment with the &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-i&amp;lt;/code&amp;gt;) option. Technically it creates a new realization of the &amp;lt;code&amp;gt;user-environment&amp;lt;/code&amp;gt; package that symlinks in the entire contents of the path path and switches to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The build log associated with a realization can be viewed with the &amp;lt;code&amp;gt;--read-log&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-l&amp;lt;/code&amp;gt;) option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --read-log $cabdrv&lt;br /&gt;
nix-store --read-log $cabpath&lt;br /&gt;
nix-store --read-log $(which git)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program also supports numerous other store related items such as computing the transitive closure of a package with the &amp;lt;code&amp;gt;--query&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-q&amp;lt;/code&amp;gt;) &amp;lt;code&amp;gt;--requisites&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-R&amp;lt;/code&amp;gt;) and exporting them via the &amp;lt;code&amp;gt;--export&amp;lt;/code&amp;gt; option to a Nix archive for import into another store.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --query --requisites $cabpath&lt;br /&gt;
nix-store --export $(nix-store --query --requisites $(which git)) | gzip &amp;amp;gt; git.nar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nix default expression ==&lt;br /&gt;
&lt;br /&gt;
Nix has a default expression created from the contents of ''~/.nix-defexpr''. The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; operation normally works by selecting an attribute in this expression (fast) or matching against the &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; attribute in all the attributes in this expression (slow) to determine an expression to instantiate, realize, and then symlink into a new environment.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix&amp;lt;/code&amp;gt; module sets up a default ''~/.nix-defexpr/nixpkgs'' that symlinks to a slightly modified version of the official Nix ''nixpkgs''. This can be entirely replace this or augment. For example, the following ''~/.nix-defexpr/mypkgs'' expression packages up the above ''cabextract.nix'' example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;args@{ ... }: with import ./nixpkgs args;&lt;br /&gt;
rec {&lt;br /&gt;
  cabextract = stdenv.mkDerivation rec {&lt;br /&gt;
    name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    src = fetchurl {&lt;br /&gt;
      url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
      sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    meta = with stdenv.lib; {&lt;br /&gt;
      homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
      description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
      platforms = platforms.all;&lt;br /&gt;
      license = licenses.gpl3;&lt;br /&gt;
      maintainers = with maintainers; [ pSub ];&lt;br /&gt;
    };&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
This makes it possible to install packages from &amp;lt;code&amp;gt;mypkgs&amp;lt;/code&amp;gt; as easily as those from the official &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr mypkgs.cabextract&amp;lt;/pre&amp;gt;&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Nix Package Manager&amp;lt;br&amp;gt;&lt;br /&gt;
http://nixos.org/nix/&lt;br /&gt;
&lt;br /&gt;
o Official Nix/Nixpkgs/NixOS&amp;lt;br&amp;gt;&lt;br /&gt;
https://github.com/NixOS&lt;br /&gt;
&lt;br /&gt;
o Nix on SHARCNET (slides by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.sharcnet.ca/help/images/5/5f/Tyson_nix_2015.pdf&lt;br /&gt;
&lt;br /&gt;
o Exploring a new approach to package management (youtube video by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.youtube.com/watch?v=pQE9WTLAPHQ&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=12492</id>
		<title>NIX</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=12492"/>
				<updated>2015-12-02T21:53:45Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=NIX&lt;br /&gt;
|package_description=User Level Purely Functional Package Manager&lt;br /&gt;
|package_idnumber=171&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
Nix is an atomic pure non-mutable package manager system that allows users to manage their own software environment.  This environment is persistent and is shared across all clusters.&lt;br /&gt;
&lt;br /&gt;
* Users can build, install, upgrade, downgrade, and remove packages from their environment without root privileges and without affecting other users&lt;br /&gt;
* Operations are atomic, they either succeed and create a new environment or fail leaving the previous environment in place.  Previous environments can be switched back to at any point.&lt;br /&gt;
&lt;br /&gt;
The default Nix package set includes a huge selection (over 10,000) of recent versions of many packages.&lt;br /&gt;
&lt;br /&gt;
=Version Selection=&lt;br /&gt;
&lt;br /&gt;
This section details how to enable your Nix environment and install and remove packages from it.  See the [[#General Notes]] section for a more advanced discussion of how Nix works and how to create your own packages.&lt;br /&gt;
&lt;br /&gt;
== Enabling and disabling the Nix environment ==&lt;br /&gt;
&lt;br /&gt;
The user's current Nix environment is enabled by loading the nix module. This creates some *.nix** files and sets some environment variables.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is disabled by unloading the nix module. This unsets the environment variables but leaves the *.nix** files alone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module unload nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&lt;br /&gt;
module load nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing, upgrading, uninstalling, and querying software ==&lt;br /&gt;
&lt;br /&gt;
The nix environment is manipulated via the &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; command. The &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-i&amp;lt;/code&amp;gt;) option is used to install software&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;git --version&lt;br /&gt;
which git&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install git&lt;br /&gt;
git --version&lt;br /&gt;
which git&amp;lt;/pre&amp;gt;&lt;br /&gt;
This takes a long time as it has to open many many files to enumerate all available software to locate the requested one by name. A faster way is to directly specify what to install by the attribute instead using the &amp;lt;code&amp;gt;--attr&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-a&amp;lt;/code&amp;gt;) option&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nixpkgs.subversion nixpkgs.mercurial&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;--upgrade&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-u&amp;lt;/code&amp;gt;) option upgrades installed software to the latest version. The &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-i&amp;lt;/code&amp;gt;) option can also be used for this purpose.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --upgrade --attr nixpkgs.git&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;--uninstall&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-e&amp;lt;/code&amp;gt;) option uninstalls software. It can be done by name or path.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --uninstall $(which svn)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The contents of the environment is queried via the &amp;lt;code&amp;gt;--query&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-q&amp;lt;/code&amp;gt;) option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --query&amp;lt;/pre&amp;gt;&lt;br /&gt;
All possible packages can be queried via the &amp;lt;code&amp;gt;--available&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-a&amp;lt;/code&amp;gt;) option. This is quite slow again due to having to enumerate all available software. Adding &amp;lt;code&amp;gt;--attr-path&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-P&amp;lt;/code&amp;gt;) includes the faster attribute paths and &amp;lt;code&amp;gt;--description&amp;lt;/code&amp;gt; includes the descriptions. It is a good idea to save this to a file for future reference.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --query --available --description --attr-path &amp;amp;gt; nix-packages.txt&lt;br /&gt;
grep git nix-packages.txt | less -S&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Environment transactions ==&lt;br /&gt;
&lt;br /&gt;
Environments are non-mutable. All &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; commands do not actually modify the current environment. Rather they create a new environment based on the existing environment and switch to it. This means all previous environments continue to exist and can be re-activated.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;--rollback&amp;lt;/code&amp;gt; option can be used to restore the previous environment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --query&lt;br /&gt;
nix-env --rollback&lt;br /&gt;
nix-env --query&amp;lt;/pre&amp;gt;&lt;br /&gt;
Previous generations of the environment can be displayed with the &amp;lt;code&amp;gt;--list-generations&amp;lt;/code&amp;gt; option and any one can be switched to with the &amp;lt;code&amp;gt;--switch-generation&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --list-generations&lt;br /&gt;
nix-env --switch-generation 3&lt;br /&gt;
nix-env --query&amp;lt;/pre&amp;gt;&lt;br /&gt;
Nix preserves any software this is accessible for any user environment. This means it is important to periodically delete older environment generations so Nix can remove the software associated with them. This is done with the &amp;lt;code&amp;gt;--delete-generations&amp;lt;/code&amp;gt; options.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --delete-generations 30d&amp;lt;/pre&amp;gt;&lt;br /&gt;
Environments are technically realizations of the Nix user-environment package.&lt;br /&gt;
&lt;br /&gt;
=Job Submission=&lt;br /&gt;
&lt;br /&gt;
Loading the Nix module before submitting a job makes the Nix environment available to the job.  Note that these jobs will see the current Nix environment including any changes made after submission.  Compiled binaries should not require the Nix module to be loaded to run.&lt;br /&gt;
&lt;br /&gt;
=Example Job=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
sqsub ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= General Notes =&lt;br /&gt;
&lt;br /&gt;
This section details some of the internals of how Nix works and how to create your own packages.  It is more advanced material not required for the basic usage detailed under the [[#Version Selection]] section above.&lt;br /&gt;
&lt;br /&gt;
== The Nix store ==&lt;br /&gt;
&lt;br /&gt;
A Nix environment is just a collection of symlinks to all the packages that exist in that environment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;readlink $(which git)&lt;br /&gt;
readlink -f ~/.nix-profile&amp;lt;/pre&amp;gt;&lt;br /&gt;
Everything in Nix exists as a path in the Nix store. Each path is distinguished with a hash of either its contents or everything that went into creating it to keep it separate from everything else. Paths are immutable once created. This means they can be freely shared.&lt;br /&gt;
&lt;br /&gt;
Paths are created by the Nix build server when it realizes a Nix derivation. Nix derivations specify all the inputs to a jailed process that creates the contents of the store path.&lt;br /&gt;
&lt;br /&gt;
== Nix expressions and instantiation ==&lt;br /&gt;
&lt;br /&gt;
Nix derivations are instantiated from Nix expressions, which are written in the Nix language. The &amp;lt;code&amp;gt;nix-repl&amp;lt;/code&amp;gt; program can be used to interactively experiment with the Nix language.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nix-repl&lt;br /&gt;
nix-repl&amp;lt;/pre&amp;gt;&lt;br /&gt;
The following ''cabextract.nix'' Nix expression evaluates to a derivation fully specifying how to build the &amp;lt;code&amp;gt;cabextract&amp;lt;/code&amp;gt; utility.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import ~/.nix-defexpr/nixpkgs { };&lt;br /&gt;
stdenv.mkDerivation rec {&lt;br /&gt;
  name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
  src = fetchurl {&lt;br /&gt;
    url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
    sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  meta = with stdenv.lib; {&lt;br /&gt;
    homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
    description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
    platforms = platforms.all;&lt;br /&gt;
    license = licenses.gpl3;&lt;br /&gt;
    maintainers = with maintainers; [ pSub ];&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is written using the &amp;lt;code&amp;gt;stdenv.mkDerivation&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;. This function creates a derivation that executes the standard unpack, patch, configure, build, check, install, fixup, check, and distribute steps on the package. It provides a series of hooks that can be used at each step to customize the process for non-standard packages.&lt;br /&gt;
&lt;br /&gt;
The Nix expression is instantiate to a derivation using &amp;lt;code&amp;gt;nix-instantiate&amp;lt;/code&amp;gt;. The leading ''./'' is required to distinguish that the arguments is file containing a Nix expression to be instantiated and not the name of a package in the default Nix expression to instantiate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabdrv=$(nix-instantiate ./cabextract.nix)&lt;br /&gt;
echo $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nix derivations and realization ==&lt;br /&gt;
&lt;br /&gt;
The Nix derivation instantiated from the above Nix expression can be pretty-printed using the &amp;lt;code&amp;gt;pp-aterm&amp;lt;/code&amp;gt; program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nixpkgs.strategoPackages.strategoxt&lt;br /&gt;
pp-aterm -i $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;Derive(&lt;br /&gt;
  [(&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)]&lt;br /&gt;
, [ (&amp;amp;quot;/home/nixbld/store/...-stdenv.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  ]&lt;br /&gt;
, [&amp;amp;quot;/home/nixbld/store/...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, &amp;amp;quot;x86_64-linux&amp;amp;quot;&lt;br /&gt;
, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;&lt;br /&gt;
, [&amp;amp;quot;-e&amp;amp;quot;, &amp;amp;quot;...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, [ (&amp;amp;quot;buildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;builder&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;name&amp;amp;quot;, &amp;amp;quot;cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;nativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedNativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;src&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;stdenv&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-stdenv&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;system&amp;amp;quot;, &amp;amp;quot;x86_64-linux&amp;amp;quot;)&lt;br /&gt;
  ]&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The Nix build server realizes derivations by building the packages in an isolated environment. Each derivation specifies what comes out of the environment, what goes into it, the required machine architecture, what build program to execute in the environment, and what arguments and environment to pass to the program to be executed.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program &amp;lt;code&amp;gt;--realize&amp;lt;/code&amp;gt; option is used to signal the build server to realize the derivation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabpath=$(nix-store --realize $cabdrv)&lt;br /&gt;
echo $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; program will add the realized derivation to the users environment with the &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-i&amp;lt;/code&amp;gt;) option. Technically it creates a new realization of the &amp;lt;code&amp;gt;user-environment&amp;lt;/code&amp;gt; package that symlinks in the entire contents of the path path and switches to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The build log associated with a realization can be viewed with the &amp;lt;code&amp;gt;--read-log&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-l&amp;lt;/code&amp;gt;) option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --read-log $cabdrv&lt;br /&gt;
nix-store --read-log $cabpath&lt;br /&gt;
nix-store --read-log $(which git)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program also supports numerous other store related items such as computing the transitive closure of a package with the &amp;lt;code&amp;gt;--query&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-q&amp;lt;/code&amp;gt;) &amp;lt;code&amp;gt;--requisites&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-R&amp;lt;/code&amp;gt;) and exporting them via the &amp;lt;code&amp;gt;--export&amp;lt;/code&amp;gt; option to a Nix archive for import into another store.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --query --requisites $cabpath&lt;br /&gt;
nix-store --export $(nix-store --query --requisites $(which git)) | gzip &amp;amp;gt; git.nar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nix default expression ==&lt;br /&gt;
&lt;br /&gt;
Nix has a default expression created from the contents of ''~/.nix-defexpr''. The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; operation normally works by selecting an attribute in this expression (fast) or matching against the &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; attribute in all the attributes in this expression (slow) to determine an expression to instantiate, realize, and then symlink into a new environment.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix&amp;lt;/code&amp;gt; module sets up a default ''~/.nix-defexpr/nixpkgs'' that symlinks to a slightly modified version of the official Nix ''nixpkgs''. This can be entirely replace this or augment. For example, the following ''~/.nix-defexpr/mypkgs'' expression packages up the above ''cabextract.nix'' example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;args@{ ... }: with import ./nixpkgs args;&lt;br /&gt;
rec {&lt;br /&gt;
  cabextract = stdenv.mkDerivation rec {&lt;br /&gt;
    name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    src = fetchurl {&lt;br /&gt;
      url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
      sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    meta = with stdenv.lib; {&lt;br /&gt;
      homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
      description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
      platforms = platforms.all;&lt;br /&gt;
      license = licenses.gpl3;&lt;br /&gt;
      maintainers = with maintainers; [ pSub ];&lt;br /&gt;
    };&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
This makes it possible to install packages from &amp;lt;code&amp;gt;mypkgs&amp;lt;/code&amp;gt; as easily as those from the official &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr mypkgs.cabextract&amp;lt;/pre&amp;gt;&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Nix Package Manager&amp;lt;br&amp;gt;&lt;br /&gt;
http://nixos.org/nix/&lt;br /&gt;
&lt;br /&gt;
o Official Nix/Nixpkgs/NixOS&amp;lt;br&amp;gt;&lt;br /&gt;
https://github.com/NixOS&lt;br /&gt;
&lt;br /&gt;
o Nix on SHARCNET (slides by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.sharcnet.ca/help/images/5/5f/Tyson_nix_2015.pdf&lt;br /&gt;
&lt;br /&gt;
o Exploring a new approach to package management (youtube video by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.youtube.com/watch?v=pQE9WTLAPHQ&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=12491</id>
		<title>NIX</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=NIX&amp;diff=12491"/>
				<updated>2015-12-02T21:52:15Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Flush out content from CO mini TECC talk&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=NIX&lt;br /&gt;
|package_description=User Level Purely Functional Package Manager&lt;br /&gt;
|package_idnumber=171&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
Nix is an atomic pure non-mutable package manager system that allows users to manage their own software environment.  This environment is persistent and is shared across all clusters.&lt;br /&gt;
&lt;br /&gt;
* Users can build, install, upgrade, downgrade, and remove packages from their environment without root privileges and without affecting other users&lt;br /&gt;
* Operations are atomic, they either succeed and create a new environment or fail leaving the previous environment in place.  Previous environments can be switched back to at any point.&lt;br /&gt;
&lt;br /&gt;
The default Nix package set includes a huge selection (over 10,000) of recent versions of many packages.&lt;br /&gt;
&lt;br /&gt;
=Version Selection=&lt;br /&gt;
&lt;br /&gt;
This section details how to enable your Nix environment and install and remove packages from it.  See the [[#General Notes]] section for a more advanced discussion of how Nix works and how to create your own packages.&lt;br /&gt;
&lt;br /&gt;
== Enabling and disabling the Nix environment ==&lt;br /&gt;
&lt;br /&gt;
The user's current Nix environment is enabled by loading the nix module. This creates some *.nix** files and sets some environment variables.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is disabled by unloading the nix module. This unsets the environment variables but leaves the *.nix** files alone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module unload nix&lt;br /&gt;
ls -ld .nix*&lt;br /&gt;
env | fgrep -i nix&lt;br /&gt;
module load nix&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing, upgrading, uninstalling, and querying software ==&lt;br /&gt;
&lt;br /&gt;
The nix environment is manipulated via the &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; command. The &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-i&amp;lt;/code&amp;gt;) option is used to install software&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;git --version&lt;br /&gt;
which git&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install git&lt;br /&gt;
git --version&lt;br /&gt;
which git&amp;lt;/pre&amp;gt;&lt;br /&gt;
This takes a long time as it has to open many many files to enumerate all available software to locate the requested one by name. A faster way is to directly specify what to install by the attribute instead using the &amp;lt;code&amp;gt;--attr&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-a&amp;lt;/code&amp;gt;) option&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nixpkgs.subversion nixpkgs.mercurial&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;--upgrade&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-u&amp;lt;/code&amp;gt;) option upgrades installed software to the latest version. The &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-i&amp;lt;/code&amp;gt;) option can also be used for this purpose.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --upgrade --attr nixpkgs.git&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;--uninstall&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-e&amp;lt;/code&amp;gt;) option uninstalls software. It can be done by name or path.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --uninstall $(which svn)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The contents of the environment is queried via the &amp;lt;code&amp;gt;--query&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-q&amp;lt;/code&amp;gt;) option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --query&amp;lt;/pre&amp;gt;&lt;br /&gt;
All possible packages can be queried via the &amp;lt;code&amp;gt;--available&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-a&amp;lt;/code&amp;gt;) option. This is quite slow again due to having to enumerate all available software. Adding &amp;lt;code&amp;gt;--attr-path&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-P&amp;lt;/code&amp;gt;) includes the faster attribute paths and &amp;lt;code&amp;gt;--description&amp;lt;/code&amp;gt; includes the descriptions. It is a good idea to save this to a file for future reference.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --query --available --description --attr-path &amp;amp;gt; nix-packages.txt&lt;br /&gt;
grep git nix-packages.txt | less -S&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Environment transactions ==&lt;br /&gt;
&lt;br /&gt;
Environments are non-mutable. All &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; commands do not actually modify the current environment. Rather they create a new environment based on the existing environment and switch to it. This means all previous environments continue to exist and can be re-activated.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;--rollback&amp;lt;/code&amp;gt; option can be used to restore the previous environment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --query&lt;br /&gt;
nix-env --rollback&lt;br /&gt;
nix-env --query&amp;lt;/pre&amp;gt;&lt;br /&gt;
Previous generations of the environment can be displayed with the &amp;lt;code&amp;gt;--list-generations&amp;lt;/code&amp;gt; option and any one can be switched to with the &amp;lt;code&amp;gt;--switch-generation&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --list-generations&lt;br /&gt;
nix-env --switch-generation 3&lt;br /&gt;
nix-env --query&amp;lt;/pre&amp;gt;&lt;br /&gt;
Nix preserves any software this is accessible for any user environment. This means it is important to periodically delete older environment generations so Nix can remove the software associated with them. This is done with the &amp;lt;code&amp;gt;--delete-generations&amp;lt;/code&amp;gt; options.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --delete-generations 30d&amp;lt;/pre&amp;gt;&lt;br /&gt;
Environments are technically realizations of the Nix user-environment package.&lt;br /&gt;
&lt;br /&gt;
=Job Submission=&lt;br /&gt;
&lt;br /&gt;
Loading the Nix module before submitting a job makes the Nix environment available to the job.  Note that these jobs will see the current Nix environment including any changes made after submission.  Compiled binaries should not require the Nix module to be loaded to run..&lt;br /&gt;
&lt;br /&gt;
=Example Job=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;module load nix&lt;br /&gt;
sqsub ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= General Notes =&lt;br /&gt;
&lt;br /&gt;
This section details some of the internals of how Nix works and how to create your own packages.  It is more advanced material not required for the basic usage detailed under the [[#Version Selection]] section above.&lt;br /&gt;
&lt;br /&gt;
== The Nix store ==&lt;br /&gt;
&lt;br /&gt;
A Nix environment is just a collection of symlinks to all the packages that exist in that environment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;readlink $(which git)&lt;br /&gt;
readlink -f ~/.nix-profile&amp;lt;/pre&amp;gt;&lt;br /&gt;
Everything in Nix exists as a path in the Nix store. Each path is distinguished with a hash of either its contents or everything that went into creating it to keep it separate from everything else. Paths are immutable once created. This means they can be freely shared.&lt;br /&gt;
&lt;br /&gt;
Paths are created by the Nix build server when it realizes a Nix derivation. Nix derivations specify all the inputs to a jailed process that creates the contents of the store path.&lt;br /&gt;
&lt;br /&gt;
== Nix expressions and instantiation ==&lt;br /&gt;
&lt;br /&gt;
Nix derivations are instantiated from Nix expressions, which are written in the Nix language. The &amp;lt;code&amp;gt;nix-repl&amp;lt;/code&amp;gt; program can be used to interactively experiment with the Nix language.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nix-repl&lt;br /&gt;
nix-repl&amp;lt;/pre&amp;gt;&lt;br /&gt;
The following ''cabextract.nix'' Nix expression evaluates to a derivation fully specifying how to build the &amp;lt;code&amp;gt;cabextract&amp;lt;/code&amp;gt; utility.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;with import ~/.nix-defexpr/nixpkgs { };&lt;br /&gt;
stdenv.mkDerivation rec {&lt;br /&gt;
  name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
  src = fetchurl {&lt;br /&gt;
    url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
    sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  meta = with stdenv.lib; {&lt;br /&gt;
    homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
    description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
    platforms = platforms.all;&lt;br /&gt;
    license = licenses.gpl3;&lt;br /&gt;
    maintainers = with maintainers; [ pSub ];&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is written using the &amp;lt;code&amp;gt;stdenv.mkDerivation&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;. This function creates a derivation that executes the standard unpack, patch, configure, build, check, install, fixup, check, and distribute steps on the package. It provides a series of hooks that can be used at each step to customize the process for non-standard packages.&lt;br /&gt;
&lt;br /&gt;
The Nix expression is instantiate to a derivation using &amp;lt;code&amp;gt;nix-instantiate&amp;lt;/code&amp;gt;. The leading ''./'' is required to distinguish that the arguments is file containing a Nix expression to be instantiated and not the name of a package in the default Nix expression to instantiate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabdrv=$(nix-instantiate ./cabextract.nix)&lt;br /&gt;
echo $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nix derivations and realization ==&lt;br /&gt;
&lt;br /&gt;
The Nix derivation instantiated from the above Nix expression can be pretty-printed using the &amp;lt;code&amp;gt;pp-aterm&amp;lt;/code&amp;gt; program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr nixpkgs.strategoPackages.strategoxt&lt;br /&gt;
pp-aterm -i $cabdrv&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;Derive(&lt;br /&gt;
  [(&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)]&lt;br /&gt;
, [ (&amp;amp;quot;/home/nixbld/store/...-stdenv.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  , (&amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42.drv&amp;amp;quot;, [&amp;amp;quot;out&amp;amp;quot;])&lt;br /&gt;
  ]&lt;br /&gt;
, [&amp;amp;quot;/home/nixbld/store/...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, &amp;amp;quot;x86_64-linux&amp;amp;quot;&lt;br /&gt;
, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;&lt;br /&gt;
, [&amp;amp;quot;-e&amp;amp;quot;, &amp;amp;quot;...-default-builder.sh&amp;amp;quot;]&lt;br /&gt;
, [ (&amp;amp;quot;buildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;builder&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-bash-4.3-p42/bin/bash&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;name&amp;amp;quot;, &amp;amp;quot;cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;nativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;out&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;propagatedNativeBuildInputs&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;src&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-cabextract-1.6.tar.gz&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;stdenv&amp;amp;quot;, &amp;amp;quot;/home/nixbld/store/...-stdenv&amp;amp;quot;)&lt;br /&gt;
  , (&amp;amp;quot;system&amp;amp;quot;, &amp;amp;quot;x86_64-linux&amp;amp;quot;)&lt;br /&gt;
  ]&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The Nix build server realizes derivations by building the packages in an isolated environment. Each derivation specifies what comes out of the environment, what goes into it, the required machine architecture, what build program to execute in the environment, and what arguments and environment to pass to the program to be executed.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program &amp;lt;code&amp;gt;--realize&amp;lt;/code&amp;gt; option is used to signal the build server to realize the derivation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;cabpath=$(nix-store --realize $cabdrv)&lt;br /&gt;
echo $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; program will add the realized derivation to the users environment with the &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-i&amp;lt;/code&amp;gt;) option. Technically it creates a new realization of the &amp;lt;code&amp;gt;user-environment&amp;lt;/code&amp;gt; package that symlinks in the entire contents of the path path and switches to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install $cabpath&amp;lt;/pre&amp;gt;&lt;br /&gt;
The build log associated with a realization can be viewed with the &amp;lt;code&amp;gt;--read-log&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-l&amp;lt;/code&amp;gt;) option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --read-log $cabdrv&lt;br /&gt;
nix-store --read-log $cabpath&lt;br /&gt;
nix-store --read-log $(which git)&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;nix-store&amp;lt;/code&amp;gt; program also supports numerous other store related items such as computing the transitive closure of a package with the &amp;lt;code&amp;gt;--query&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-q&amp;lt;/code&amp;gt;) &amp;lt;code&amp;gt;--requisites&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;-R&amp;lt;/code&amp;gt;) and exporting them via the &amp;lt;code&amp;gt;--export&amp;lt;/code&amp;gt; option to a Nix archive for import into another store.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-store --query --requisites $cabpath&lt;br /&gt;
nix-store --export $(nix-store --query --requisites $(which git)) | gzip &amp;amp;gt; git.nar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nix default expression ==&lt;br /&gt;
&lt;br /&gt;
Nix has a default expression created from the contents of ''~/.nix-defexpr''. The &amp;lt;code&amp;gt;nix-env&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;--install&amp;lt;/code&amp;gt; operation normally works by selecting an attribute in this expression (fast) or matching against the &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; attribute in all the attributes in this expression (slow) to determine an expression to instantiate, realize, and then symlink into a new environment.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;nix&amp;lt;/code&amp;gt; module sets up a default ''~/.nix-defexpr/nixpkgs'' that symlinks to a slightly modified version of the official Nix ''nixpkgs''. This can be entirely replace this or augment. For example, the following ''~/.nix-defexpr/mypkgs'' expression packages up the above ''cabextract.nix'' example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;nix&amp;quot;&amp;gt;args@{ ... }: with import ./nixpkgs args;&lt;br /&gt;
rec {&lt;br /&gt;
  cabextract = stdenv.mkDerivation rec {&lt;br /&gt;
    name = &amp;amp;quot;cabextract-1.6&amp;amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    src = fetchurl {&lt;br /&gt;
      url = &amp;amp;quot;http://www.cabextract.org.uk/${name}.tar.gz&amp;amp;quot;;&lt;br /&gt;
      sha256 = &amp;amp;quot;1ysmmz25fjghq7mxb2anyyvr1ljxqxzi4piwjhk0sdamcnsn3rnf&amp;amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    meta = with stdenv.lib; {&lt;br /&gt;
      homepage = http://www.cabextract.org.uk/;&lt;br /&gt;
      description = &amp;amp;quot;Free Software for extracting Microsoft cabinet files&amp;amp;quot;;&lt;br /&gt;
      platforms = platforms.all;&lt;br /&gt;
      license = licenses.gpl3;&lt;br /&gt;
      maintainers = with maintainers; [ pSub ];&lt;br /&gt;
    };&lt;br /&gt;
  };&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
This makes it possible to install packages from &amp;lt;code&amp;gt;mypkgs&amp;lt;/code&amp;gt; as easily as those from the official &amp;lt;code&amp;gt;nixpkgs&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;sh&amp;quot;&amp;gt;nix-env --install --attr mypkgs.cabextract&amp;lt;/pre&amp;gt;&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Nix Package Manager&amp;lt;br&amp;gt;&lt;br /&gt;
http://nixos.org/nix/&lt;br /&gt;
&lt;br /&gt;
o Official Nix/Nixpkgs/NixOS&amp;lt;br&amp;gt;&lt;br /&gt;
https://github.com/NixOS&lt;br /&gt;
&lt;br /&gt;
o Nix on SHARCNET (slides by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.sharcnet.ca/help/images/5/5f/Tyson_nix_2015.pdf&lt;br /&gt;
&lt;br /&gt;
o Exploring a new approach to package management (youtube video by Tyson Whitehead)&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.youtube.com/watch?v=pQE9WTLAPHQ&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11909</id>
		<title>VALGRIND</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11909"/>
				<updated>2015-09-22T15:25:21Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Clarify what is the valgrind enabled openmpi debug library&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=VALGRIND&lt;br /&gt;
|package_description=Memory debugger&lt;br /&gt;
|package_idnumber=132&lt;br /&gt;
}}&lt;br /&gt;
'''Valgrind''' is a powerful tool for analyzing programs, memory debugging, memory leak detection and profiling.  It is freely available under GNU license.  Version 3.5.0 is available on most SHARCNET systems.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' To avoid spurious warnings it is important to not use too new of a version of GCC or OpenMPI.  We recommend&lt;br /&gt;
&lt;br /&gt;
* gcc/4.8.2&lt;br /&gt;
* openmpi/gcc-debug/1.8.3 modules&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Valgrind is a dynamic binary instrumentation framework that dynamically translates executables to add instrumentation and track all memory and register usages by a program.  The advantages of this approach are that&lt;br /&gt;
&lt;br /&gt;
* it can be directly run on any executable, and&lt;br /&gt;
* dynamic translation allows ultimate instrumentation&lt;br /&gt;
&lt;br /&gt;
while the disadvantages are&lt;br /&gt;
&lt;br /&gt;
* 5-100 x slow down depending on tool,&lt;br /&gt;
* 12-18 x increase in size of translated code, and&lt;br /&gt;
* corner cases may exist between translated code and original.&lt;br /&gt;
&lt;br /&gt;
Several tools have been built upon this framework.  These include&lt;br /&gt;
&lt;br /&gt;
* ''memcheck'' -  memory error detector&lt;br /&gt;
* ''cachegrind'' - cache and branch-prediction profiler&lt;br /&gt;
* ''callgrind'' - call-graph generating cache and branch prediction profiler&lt;br /&gt;
* ''helgrind'' - thread error detector&lt;br /&gt;
* ''DRD'' - thread error detector&lt;br /&gt;
* ''Massif'' - heap profiler&lt;br /&gt;
* ''DHAT'' - dynamic heap analysis tool&lt;br /&gt;
* ''SGCheck'' - experimental stack and global array overrun detector&lt;br /&gt;
* ''BBV'' - experimental basic block vector generation tool&lt;br /&gt;
&lt;br /&gt;
You are welcome to use any or all of these, but we have only used ''memcheck'' and ''cachegrind'' and only support ''memcheck''.&lt;br /&gt;
&lt;br /&gt;
= Usage =&lt;br /&gt;
&lt;br /&gt;
The primary used tool is ''memcheck''.  This is the default tool and the only one we discuss here.  Documentation for other tools can be found on the [http://www.valgrind.org valgrind website].  The memcheck tool detects several common memory errors&lt;br /&gt;
&lt;br /&gt;
* overrunning and underrunning heap blocks,&lt;br /&gt;
* overrunning top of stack,&lt;br /&gt;
* continuing to access released memory,&lt;br /&gt;
* using uninitialized values,&lt;br /&gt;
* incorrectly using memory copying routines,&lt;br /&gt;
* incorrectly paired allocation/release calls,&lt;br /&gt;
* relasing unallocated memory, and&lt;br /&gt;
* not releasing memory.&lt;br /&gt;
&lt;br /&gt;
We recommend running all new code under valgrind on small test cases (small due to the aforementioned ~10x slowdown).  This can save hours and hours of debugging.  Running the program under valgrind can be as simple as compiling with debugging information (adding the &amp;lt;tt&amp;gt;-g&amp;lt;/tt&amp;gt; flag) and running as &amp;lt;tt&amp;gt;valgrind &amp;lt;program&amp;gt; &amp;lt;arguements&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Serial code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
&lt;br /&gt;
  // Execution depends on uninitialized value&lt;br /&gt;
  if (array[4] &amp;lt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is negative\n&amp;quot;);&lt;br /&gt;
  else if (array[4] == 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is zero\n&amp;quot;);&lt;br /&gt;
  else if (array[4] &amp;gt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is positive\n&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    printf(&amp;quot;the results are special\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug.  Running this under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reports this&lt;br /&gt;
&lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400511: main (bug.c:7)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x40052C: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400536: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400551: main (bug.c:11)&lt;br /&gt;
&lt;br /&gt;
Note that valgrind only reports uninitialized values usage once they lead to non-determinism (i.e., when the program encounters a branch whose choice depends on the result of an uninitiated value).  This means you the first report you get is frequently not in the calculation done on the uninitialized values but rather the convergence test or print statement at the end of calculations (print statements contains a bunch of branches in order to handling printing of each different digit).&lt;br /&gt;
&lt;br /&gt;
=== Tracking down uninitialized values ===&lt;br /&gt;
&lt;br /&gt;
More typically a program will be composed of multiple routines that all work on the data.  To this end, consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_sequence(double* array, const int array_length) {&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=1; i&amp;lt;array_length+1; ++i)&lt;br /&gt;
    array[i] = i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
  const int array_length = sizeof(array)/sizeof(array[0]);&lt;br /&gt;
&lt;br /&gt;
  double array_sum;&lt;br /&gt;
&lt;br /&gt;
  initialize_sequence(array,array_length);&lt;br /&gt;
  array_sum = sum(array,array_length);&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;the sum of 0..%d is %f\n&amp;quot;, array_length-1, array_sum);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has both indexing and uninitialized value bugs.  Despite this, directly running the code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will mostly likely produce the correct answer on most machines most of the time&lt;br /&gt;
&lt;br /&gt;
 the sum of 0..9 is 45.000000&lt;br /&gt;
&lt;br /&gt;
Running under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reliably gives many warnings of the following form&lt;br /&gt;
&lt;br /&gt;
 ==15930== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==15930==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x400722: main (bug.c:29)&lt;br /&gt;
&lt;br /&gt;
This is a typical numeric code example were the warnings first occur at a print statement because this is the first time the uninitialized value leads to non-determinism (i.e., the program's behaviour is random as it is taking or does not taking a branch based on a result computed from something that was not set by the programmer).&lt;br /&gt;
&lt;br /&gt;
We now know the problem is that something unset went into computing the value of ''array_sum'', so we should trace the ''array_sum'' calculation backwards through the program.  This quickly gets difficult as we then find ourselves also tracing back all variables that went into the ''array_sum'' calculation, and then all variables that went into those variables, and so on.&lt;br /&gt;
&lt;br /&gt;
Fortunately Valgrind provides a &amp;lt;tt&amp;gt;--track-origins=yes&amp;lt;/tt&amp;gt; flag to ease our search by telling us which variables are the source of the problem.  Re-running with this flag&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
valgrind --track-origins=yes ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gives warning messages augmented to include the source of the uninitialized value that went into the computation of ''array_sum''&lt;br /&gt;
&lt;br /&gt;
 ==17589== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==17589==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x400722: main (bug.c:29)&lt;br /&gt;
 ==17589==  Uninitialised value was created by a stack allocation&lt;br /&gt;
 ==17589==    at 0x400632: sum (bug.c:10)&lt;br /&gt;
&lt;br /&gt;
Now we know the source of the uninitialized value in the ''array_sum'' computation was a local variable in the ''sum'' routine.  Looking into ''sum'' we hopefully figure out without too much difficulty that we forgot to initialize ''array_sum'' to zero.  If our program is producing the correct answer, it is only because we are getting lucky and ''array_sum'' happens to be allocated from memory that is initially zero.&lt;br /&gt;
&lt;br /&gt;
Correcting the ''sum'' routine&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  array_sum = 0.0;&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and re-running under valgrind reveals we are still getting uninitialized values warnings associated with the ''array_sum'' computation.  Now (using the &amp;lt;tt&amp;gt;--track-origins=yes&amp;lt;/tt&amp;gt;) they are of the form&lt;br /&gt;
&lt;br /&gt;
 ==18613== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==18613==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x40072C: main (bug.c:30)&lt;br /&gt;
 ==18613==  Uninitialised value was created by a stack allocation&lt;br /&gt;
 ==18613==    at 0x400690: main (bug.c:21)&lt;br /&gt;
&lt;br /&gt;
Valgrind is now telling us that a local variable inside ''main'' went into the computation of ''array_sum'' despite never being set.  This must be ''array'' itself as ''array_length'' is clearly set to the compiler computed &amp;lt;tt&amp;gt;sizeof(array)/sizeof(array[0])&amp;lt;/tt&amp;gt; value.&lt;br /&gt;
&lt;br /&gt;
Looking at ''main'' it is clear ''array'' should have been fully initialized by ''initialize_sequence''.  Careful examination of this routine reveals the final error.  The initialization loop was done using Fortran indices (1...''array_length'')  instead of C (0...''array_length-1'').  Correcting this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
void initialize_sequence(double* array, const int array_length) {&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array[i] = i;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
finally produces code the runs under valgrind without any warnings.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' The Valgrind warnings were being generated because the ''array[0]'' value was not being initialized.  The code was also incorrect in that it was initializing ''array[array_length]'' which is one past the end of ''array''.  If you put this later error back into the program and run under Valgrind you will discover it does not produce any warnings.  This shows that even codes that successfully under Valgrind can still contain errors.&lt;br /&gt;
&lt;br /&gt;
=== Calling Valgrind from your program ===&lt;br /&gt;
&lt;br /&gt;
In some cases it can be helpful to call Valgrind directly from your program in order to check the status of various bits of memory.  This is easily done by including the ''valgrind/memcheck.h'' header file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;valgrind/memcheck.h&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and then adding calls to the appropriate [http://valgrind.org/docs/manual/mc-manual.html#mc-manual.clientreqs client check routines].  For example, here is a modified ''sum'' routine for the above program that prints a warning if it is called with an ''array'' that is not fully initialized&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  if (VALGRIND_CHECK_MEM_IS_DEFINED(array,sizeof(double)*array_length)) &lt;br /&gt;
    fprintf(stderr,&amp;quot;sum called with an array that is not fully defined...\n&amp;quot;); &lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the ''bug.c'' code under Valgrind with this modification produces the following output&lt;br /&gt;
&lt;br /&gt;
 ==29765== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==29765==    at 0x400745: sum (bug.c:15)&lt;br /&gt;
 ==29765==    by 0x400832: main (bug.c:31)&lt;br /&gt;
 ==29765==  Address 0x7fefff8e8 is on thread 1's stack&lt;br /&gt;
 ==29765== &lt;br /&gt;
 sum called with an array that is not fully defined...&lt;br /&gt;
&lt;br /&gt;
== MPI code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' MPI code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;mpi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc,char *argv[]){&lt;br /&gt;
  int rank, size;&lt;br /&gt;
  int value;&lt;br /&gt;
&lt;br /&gt;
  MPI_Init(&amp;amp;argc, &amp;amp;argv);&lt;br /&gt;
&lt;br /&gt;
  MPI_Comm_rank(MPI_COMM_WORLD, &amp;amp;rank);&lt;br /&gt;
  MPI_Comm_size(MPI_COMM_WORLD, &amp;amp;size);&lt;br /&gt;
&lt;br /&gt;
  if (rank == 0 &amp;amp;&amp;amp; size &amp;gt; 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Irecv(&amp;amp;value, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 0;&lt;br /&gt;
    MPI_Wait (&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  }&lt;br /&gt;
  else if (rank == 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Isend(&amp;amp;value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 1;&lt;br /&gt;
    MPI_Wait(&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  } &lt;br /&gt;
&lt;br /&gt;
  MPI_Finalize();&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug and two race condition bugs around the use of value.&lt;br /&gt;
&lt;br /&gt;
# The first race condition is that rank==0 sets value=0 while at the same time doing a non-blocking receive into value (bug:16).&lt;br /&gt;
# The uninitialized value problem is that rank==1 starts a send of value to rank==0 without ever setting value (bug:22).&lt;br /&gt;
# The second race condition is that rank==1 sets value=1 while at the same time doing a non-blocking send of value (bug:23).&lt;br /&gt;
&lt;br /&gt;
=== Basic Functionality ===&lt;br /&gt;
&lt;br /&gt;
If we just straight up compile and run this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load gcc/4.8.2 openmpi/gcc/1.8.3&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we presumably get a report about the uninitialized value, but it is buried in tens of thousands of other bogus error messages.&lt;br /&gt;
&lt;br /&gt;
This solution is to link against the valgrind openmpi debug wrapper library too&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpicc -Wall -g bug.c -L/usr/lib64/valgrind -lmpiwrap-amd64-linux -Xlinker -rpath=/usr/lib64/valgrind -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now there are only a few bogus errors reported of the form&lt;br /&gt;
&lt;br /&gt;
 ==12598== Syscall param write(buf) points to uninitialised byte(s)&lt;br /&gt;
 ==12598==    at 0x53916FD: ??? (in /lib64/libpthread-2.12.so)&lt;br /&gt;
 ==12598==    by 0x8AC8E40: send_bytes (oob_tcp_sendrecv.c:84)&lt;br /&gt;
 ==12598==    by 0x8AC9471: mca_oob_tcp_send_handler (oob_tcp_sendrecv.c:205)&lt;br /&gt;
 ==12598==    by 0x616FA23: opal_libevent2021_event_base_loop (in /opt/sharcnet/openmpi/1.8.1/gcc-debug/lib/libopen-pal.so.6.1.1)&lt;br /&gt;
 ==12598==    by 0x5B7E78D: orte_progress_thread_engine (ess_base_std_app.c:456)&lt;br /&gt;
 ==12598==    by 0x538A9D0: start_thread (in /lib64/libpthread-2.12.so)&lt;br /&gt;
 ==12598==    by 0x8AB86FF: ???&lt;br /&gt;
&lt;br /&gt;
We know this isn't an issue with ''bug.c'' as the backtrace shows it is occurring in a pure OpenMPI thread (the backtrace starts with ''start_thread'' and all subsequent routines are not from ''bug.c'').  Skipping over these we now see Valgrind is picking up on sending the uninitialized value&lt;br /&gt;
&lt;br /&gt;
 ==12599== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==12599==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==12599==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==12599==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==12599==    by 0x400B02: main (bug.c:22)&lt;br /&gt;
 ==12599==  Address 0x7fefff5c4 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' If we want to avoid recompiling our program, we can also preload the ''mpiwrap-amd64-linux'' library instead of linking against it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
LD_LIBRARY_PATH=&amp;quot;$(which mpirun | sed -e 's|/bin/.*$|/lib|')${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}&amp;quot; \&lt;br /&gt;
LD_PRELOAD=/usr/lib64/valgrind/libmpiwrap-amd64-linux.so mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Breaking out output by rank ===&lt;br /&gt;
&lt;br /&gt;
By default the Valgrind output from all the MPI ranks gets intermingled together on stderr.  Although they can be distinguished for the most part as each line is prefixed with the process number, it is frequently nice to write them out to individual files.  This can be done by using the ''mpirun'' &amp;lt;tt&amp;gt;--output-filename &amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt; option.  It captures the output of each rank to ''&amp;lt;filename&amp;gt;'' suffixed with the ''MPI_COMM_WORLD'' rank&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpirun --output-filename bug.log -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To redirect just the Valgrind output we need to use the Valgrind &amp;lt;tt&amp;gt;--log-file=&amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt; option with the special &amp;lt;tt&amp;gt;%q{&amp;lt;environment-variable&amp;gt;}&amp;lt;/tt&amp;gt; syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpirun -np 2 valgrind --log-file=bug.log-%q{OMPI_COMM_WORLD_RANK} ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Both of the above can also be done by wrapping the Valgrind call with Bash to perform redirection and/or environment variable expansion&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpirun -np 2 /bin/bash -c 'exec valgrind ./bug &amp;gt; bug.log-$OMPI_COMM_WORLD_RANK 2&amp;gt;&amp;amp;1'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpirun -np 2 /bin/bash -c 'exec valgrind --log-file=bug.log-$OMPI_COMM_WORLD_RANK ./bug'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Advanced Functionality ===&lt;br /&gt;
&lt;br /&gt;
Now, if on top of this, we also bring in the valgrind enabled openmpi debug library (i.e., the ''debug'' version of our ''openmpi'' module), things get really sweet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload gcc openmpi&lt;br /&gt;
module load gcc/4.8.2 openmpi/gcc-debug/1.8.3&lt;br /&gt;
mpicc -Wall -g bug.c -L/usr/lib64/valgrind -lmpiwrap-amd64-linux -Xlinker -rpath=/usr/lib64/valgrind -o bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now all the bugs in the code are detected and reported&lt;br /&gt;
&lt;br /&gt;
 ==27774== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27774==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27774==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27774==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27774==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27773== Invalid write of size 4&lt;br /&gt;
 ==27773==    at 0x4026A0: main (bug.c:16)&lt;br /&gt;
 ==27773==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27774== Invalid write of size 4&lt;br /&gt;
 ==27774==    at 0x40271B: main (bug.c:23)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Suppression File ===&lt;br /&gt;
&lt;br /&gt;
There is also a valgrind suppression option &amp;lt;tt&amp;gt;--suppressions=&amp;quot;$(which mpirun | sed -e 's|/bin/.*|/share/openmpi/openmpi-valgrind.supp|')&amp;quot;&amp;lt;/tt&amp;gt;.  We have not observed any cases where this makes a difference yet though.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Package website&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.valgrind.org&lt;br /&gt;
&lt;br /&gt;
[[Category:Software packages]]&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11813</id>
		<title>VALGRIND</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11813"/>
				<updated>2015-09-08T20:32:46Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Add details about splitting out output by ranks&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=VALGRIND&lt;br /&gt;
|package_description=Memory debugger&lt;br /&gt;
|package_idnumber=132&lt;br /&gt;
}}&lt;br /&gt;
'''Valgrind''' is a powerful tool for analyzing programs, memory debugging, memory leak detection and profiling.  It is freely available under GNU license.  Version 3.5.0 is available on most SHARCNET systems.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' To avoid spurious warnings it is important to not use too new of a version of GCC or OpenMPI.  We recommend&lt;br /&gt;
&lt;br /&gt;
* gcc/4.8.2&lt;br /&gt;
* openmpi/gcc-debug/1.8.3 modules&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Valgrind is a dynamic binary instrumentation framework that dynamically translates executables to add instrumentation and track all memory and register usages by a program.  The advantages of this approach are that&lt;br /&gt;
&lt;br /&gt;
* it can be directly run on any executable, and&lt;br /&gt;
* dynamic translation allows ultimate instrumentation&lt;br /&gt;
&lt;br /&gt;
while the disadvantages are&lt;br /&gt;
&lt;br /&gt;
* 5-100 x slow down depending on tool,&lt;br /&gt;
* 12-18 x increase in size of translated code, and&lt;br /&gt;
* corner cases may exist between translated code and original.&lt;br /&gt;
&lt;br /&gt;
Several tools have been built upon this framework.  These include&lt;br /&gt;
&lt;br /&gt;
* ''memcheck'' -  memory error detector&lt;br /&gt;
* ''cachegrind'' - cache and branch-prediction profiler&lt;br /&gt;
* ''callgrind'' - call-graph generating cache and branch prediction profiler&lt;br /&gt;
* ''helgrind'' - thread error detector&lt;br /&gt;
* ''DRD'' - thread error detector&lt;br /&gt;
* ''Massif'' - heap profiler&lt;br /&gt;
* ''DHAT'' - dynamic heap analysis tool&lt;br /&gt;
* ''SGCheck'' - experimental stack and global array overrun detector&lt;br /&gt;
* ''BBV'' - experimental basic block vector generation tool&lt;br /&gt;
&lt;br /&gt;
You are welcome to use any or all of these, but we have only used ''memcheck'' and ''cachegrind'' and only support ''memcheck''.&lt;br /&gt;
&lt;br /&gt;
= Usage =&lt;br /&gt;
&lt;br /&gt;
The primary used tool is ''memcheck''.  This is the default tool and the only one we discuss here.  Documentation for other tools can be found on the [http://www.valgrind.org valgrind website].  The memcheck tool detects several common memory errors&lt;br /&gt;
&lt;br /&gt;
* overrunning and underrunning heap blocks,&lt;br /&gt;
* overrunning top of stack,&lt;br /&gt;
* continuing to access released memory,&lt;br /&gt;
* using uninitialized values,&lt;br /&gt;
* incorrectly using memory copying routines,&lt;br /&gt;
* incorrectly paired allocation/release calls,&lt;br /&gt;
* relasing unallocated memory, and&lt;br /&gt;
* not releasing memory.&lt;br /&gt;
&lt;br /&gt;
We recommend running all new code under valgrind on small test cases (small due to the aforementioned ~10x slowdown).  This can save hours and hours of debugging.  Running the program under valgrind can be as simple as compiling with debugging information (adding the &amp;lt;tt&amp;gt;-g&amp;lt;/tt&amp;gt; flag) and running as &amp;lt;tt&amp;gt;valgrind &amp;lt;program&amp;gt; &amp;lt;arguements&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Serial code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
&lt;br /&gt;
  // Execution depends on uninitialized value&lt;br /&gt;
  if (array[4] &amp;lt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is negative\n&amp;quot;);&lt;br /&gt;
  else if (array[4] == 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is zero\n&amp;quot;);&lt;br /&gt;
  else if (array[4] &amp;gt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is positive\n&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    printf(&amp;quot;the results are special\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug.  Running this under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reports this&lt;br /&gt;
&lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400511: main (bug.c:7)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x40052C: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400536: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400551: main (bug.c:11)&lt;br /&gt;
&lt;br /&gt;
Note that valgrind only reports uninitialized values usage once they lead to non-determinism (i.e., when the program encounters a branch whose choice depends on the result of an uninitiated value).  This means you the first report you get is frequently not in the calculation done on the uninitialized values but rather the convergence test or print statement at the end of calculations (print statements contains a bunch of branches in order to handling printing of each different digit).&lt;br /&gt;
&lt;br /&gt;
=== Tracking down uninitialized values ===&lt;br /&gt;
&lt;br /&gt;
More typically a program will be composed of multiple routines that all work on the data.  To this end, consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_sequence(double* array, const int array_length) {&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=1; i&amp;lt;array_length+1; ++i)&lt;br /&gt;
    array[i] = i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
  const int array_length = sizeof(array)/sizeof(array[0]);&lt;br /&gt;
&lt;br /&gt;
  double array_sum;&lt;br /&gt;
&lt;br /&gt;
  initialize_sequence(array,array_length);&lt;br /&gt;
  array_sum = sum(array,array_length);&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;the sum of 0..%d is %f\n&amp;quot;, array_length-1, array_sum);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has both indexing and uninitialized value bugs.  Despite this, directly running the code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will mostly likely produce the correct answer on most machines most of the time&lt;br /&gt;
&lt;br /&gt;
 the sum of 0..9 is 45.000000&lt;br /&gt;
&lt;br /&gt;
Running under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reliably gives many warnings of the following form&lt;br /&gt;
&lt;br /&gt;
 ==15930== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==15930==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x400722: main (bug.c:29)&lt;br /&gt;
&lt;br /&gt;
This is a typical numeric code example were the warnings first occur at a print statement because this is the first time the uninitialized value leads to non-determinism (i.e., the program's behaviour is random as it is taking or does not taking a branch based on a result computed from something that was not set by the programmer).&lt;br /&gt;
&lt;br /&gt;
We now know the problem is that something unset went into computing the value of ''array_sum'', so we should trace the ''array_sum'' calculation backwards through the program.  This quickly gets difficult as we then find ourselves also tracing back all variables that went into the ''array_sum'' calculation, and then all variables that went into those variables, and so on.&lt;br /&gt;
&lt;br /&gt;
Fortunately Valgrind provides a &amp;lt;tt&amp;gt;--track-origins=yes&amp;lt;/tt&amp;gt; flag to ease our search by telling us which variables are the source of the problem.  Re-running with this flag&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
valgrind --track-origins=yes ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gives warning messages augmented to include the source of the uninitialized value that went into the computation of ''array_sum''&lt;br /&gt;
&lt;br /&gt;
 ==17589== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==17589==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x400722: main (bug.c:29)&lt;br /&gt;
 ==17589==  Uninitialised value was created by a stack allocation&lt;br /&gt;
 ==17589==    at 0x400632: sum (bug.c:10)&lt;br /&gt;
&lt;br /&gt;
Now we know the source of the uninitialized value in the ''array_sum'' computation was a local variable in the ''sum'' routine.  Looking into ''sum'' we hopefully figure out without too much difficulty that we forgot to initialize ''array_sum'' to zero.  If our program is producing the correct answer, it is only because we are getting lucky and ''array_sum'' happens to be allocated from memory that is initially zero.&lt;br /&gt;
&lt;br /&gt;
Correcting the ''sum'' routine&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  array_sum = 0.0;&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and re-running under valgrind reveals we are still getting uninitialized values warnings associated with the ''array_sum'' computation.  Now (using the &amp;lt;tt&amp;gt;--track-origins=yes&amp;lt;/tt&amp;gt;) they are of the form&lt;br /&gt;
&lt;br /&gt;
 ==18613== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==18613==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x40072C: main (bug.c:30)&lt;br /&gt;
 ==18613==  Uninitialised value was created by a stack allocation&lt;br /&gt;
 ==18613==    at 0x400690: main (bug.c:21)&lt;br /&gt;
&lt;br /&gt;
Valgrind is now telling us that a local variable inside ''main'' went into the computation of ''array_sum'' despite never being set.  This must be ''array'' itself as ''array_length'' is clearly set to the compiler computed &amp;lt;tt&amp;gt;sizeof(array)/sizeof(array[0])&amp;lt;/tt&amp;gt; value.&lt;br /&gt;
&lt;br /&gt;
Looking at ''main'' it is clear ''array'' should have been fully initialized by ''initialize_sequence''.  Careful examination of this routine reveals the final error.  The initialization loop was done using Fortran indices (1...''array_length'')  instead of C (0...''array_length-1'').  Correcting this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
void initialize_sequence(double* array, const int array_length) {&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array[i] = i;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
finally produces code the runs under valgrind without any warnings.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' The Valgrind warnings were being generated because the ''array[0]'' value was not being initialized.  The code was also incorrect in that it was initializing ''array[array_length]'' which is one past the end of ''array''.  If you put this later error back into the program and run under Valgrind you will discover it does not produce any warnings.  This shows that even codes that successfully under Valgrind can still contain errors.&lt;br /&gt;
&lt;br /&gt;
=== Calling Valgrind from your program ===&lt;br /&gt;
&lt;br /&gt;
In some cases it can be helpful to call Valgrind directly from your program in order to check the status of various bits of memory.  This is easily done by including the ''valgrind/memcheck.h'' header file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;valgrind/memcheck.h&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and then adding calls to the appropriate [http://valgrind.org/docs/manual/mc-manual.html#mc-manual.clientreqs client check routines].  For example, here is a modified ''sum'' routine for the above program that prints a warning if it is called with an ''array'' that is not fully initialized&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  if (VALGRIND_CHECK_MEM_IS_DEFINED(array,sizeof(double)*array_length)) &lt;br /&gt;
    fprintf(stderr,&amp;quot;sum called with an array that is not fully defined...\n&amp;quot;); &lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the ''bug.c'' code under Valgrind with this modification produces the following output&lt;br /&gt;
&lt;br /&gt;
 ==29765== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==29765==    at 0x400745: sum (bug.c:15)&lt;br /&gt;
 ==29765==    by 0x400832: main (bug.c:31)&lt;br /&gt;
 ==29765==  Address 0x7fefff8e8 is on thread 1's stack&lt;br /&gt;
 ==29765== &lt;br /&gt;
 sum called with an array that is not fully defined...&lt;br /&gt;
&lt;br /&gt;
== MPI code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' MPI code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;mpi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc,char *argv[]){&lt;br /&gt;
  int rank, size;&lt;br /&gt;
  int value;&lt;br /&gt;
&lt;br /&gt;
  MPI_Init(&amp;amp;argc, &amp;amp;argv);&lt;br /&gt;
&lt;br /&gt;
  MPI_Comm_rank(MPI_COMM_WORLD, &amp;amp;rank);&lt;br /&gt;
  MPI_Comm_size(MPI_COMM_WORLD, &amp;amp;size);&lt;br /&gt;
&lt;br /&gt;
  if (rank == 0 &amp;amp;&amp;amp; size &amp;gt; 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Irecv(&amp;amp;value, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 0;&lt;br /&gt;
    MPI_Wait (&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  }&lt;br /&gt;
  else if (rank == 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Isend(&amp;amp;value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 1;&lt;br /&gt;
    MPI_Wait(&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  } &lt;br /&gt;
&lt;br /&gt;
  MPI_Finalize();&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug and two race condition bugs around the use of value.&lt;br /&gt;
&lt;br /&gt;
# The first race condition is that rank==0 sets value=0 while at the same time doing a non-blocking receive into value (bug:16).&lt;br /&gt;
# The uninitialized value problem is that rank==1 starts a send of value to rank==0 without ever setting value (bug:22).&lt;br /&gt;
# The second race condition is that rank==1 sets value=1 while at the same time doing a non-blocking send of value (bug:23).&lt;br /&gt;
&lt;br /&gt;
=== Basic Functionality ===&lt;br /&gt;
&lt;br /&gt;
If we just straight up compile and run this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load gcc/4.8.2 openmpi/gcc/1.8.3&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we presumably get a report about the uninitialized value, but it is buried in tens of thousands of other bogus error messages.&lt;br /&gt;
&lt;br /&gt;
This solution is to link against the valgrind openmpi debug wrapper library too&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpicc -Wall -g bug.c -L/usr/lib64/valgrind -lmpiwrap-amd64-linux -Xlinker -rpath=/usr/lib64/valgrind -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now there are only a few bogus errors reported of the form&lt;br /&gt;
&lt;br /&gt;
 ==12598== Syscall param write(buf) points to uninitialised byte(s)&lt;br /&gt;
 ==12598==    at 0x53916FD: ??? (in /lib64/libpthread-2.12.so)&lt;br /&gt;
 ==12598==    by 0x8AC8E40: send_bytes (oob_tcp_sendrecv.c:84)&lt;br /&gt;
 ==12598==    by 0x8AC9471: mca_oob_tcp_send_handler (oob_tcp_sendrecv.c:205)&lt;br /&gt;
 ==12598==    by 0x616FA23: opal_libevent2021_event_base_loop (in /opt/sharcnet/openmpi/1.8.1/gcc-debug/lib/libopen-pal.so.6.1.1)&lt;br /&gt;
 ==12598==    by 0x5B7E78D: orte_progress_thread_engine (ess_base_std_app.c:456)&lt;br /&gt;
 ==12598==    by 0x538A9D0: start_thread (in /lib64/libpthread-2.12.so)&lt;br /&gt;
 ==12598==    by 0x8AB86FF: ???&lt;br /&gt;
&lt;br /&gt;
We know this isn't an issue with ''bug.c'' as the backtrace shows it is occurring in a pure OpenMPI thread (the backtrace starts with ''start_thread'' and all subsequent routines are not from ''bug.c'').  Skipping over these we now see Valgrind is picking up on sending the uninitialized value&lt;br /&gt;
&lt;br /&gt;
 ==12599== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==12599==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==12599==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==12599==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==12599==    by 0x400B02: main (bug.c:22)&lt;br /&gt;
 ==12599==  Address 0x7fefff5c4 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' If we want to avoid recompiling our program, we can also preload the ''mpiwrap-amd64-linux'' library instead of linking against it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
LD_LIBRARY_PATH=&amp;quot;$(which mpirun | sed -e 's|/bin/.*$|/lib|')${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}&amp;quot; \&lt;br /&gt;
LD_PRELOAD=/usr/lib64/valgrind/libmpiwrap-amd64-linux.so mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Breaking out output by rank ===&lt;br /&gt;
&lt;br /&gt;
By default the Valgrind output from all the MPI ranks gets intermingled together on stderr.  Although they can be distinguished for the most part as each line is prefixed with the process number, it is frequently nice to write them out to individual files.  This can be done by using the ''mpirun'' &amp;lt;tt&amp;gt;--output-filename &amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt; option.  It captures the output of each rank to ''&amp;lt;filename&amp;gt;'' suffixed with the ''MPI_COMM_WORLD'' rank&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpirun --output-filename bug.log -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To redirect just the Valgrind output we need to use the Valgrind &amp;lt;tt&amp;gt;--log-file=&amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt; option with the special &amp;lt;tt&amp;gt;%q{&amp;lt;environment-variable&amp;gt;}&amp;lt;/tt&amp;gt; syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpirun -np 2 valgrind --log-file=bug.log-%q{OMPI_COMM_WORLD_RANK} ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Both of the above can also be done by wrapping the Valgrind call with Bash to perform redirection and/or environment variable expansion&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpirun -np 2 /bin/bash -c 'exec valgrind ./bug &amp;gt; bug.log-$OMPI_COMM_WORLD_RANK 2&amp;gt;&amp;amp;1'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpirun -np 2 /bin/bash -c 'exec valgrind --log-file=bug.log-$OMPI_COMM_WORLD_RANK ./bug'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Advanced Functionality ===&lt;br /&gt;
&lt;br /&gt;
Now, if on top of this, we also bring in the valgrind enabled openmpi debug library, things get really sweet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload gcc openmpi&lt;br /&gt;
module load gcc/4.8.2 openmpi/gcc-debug/1.8.3&lt;br /&gt;
mpicc -Wall -g bug.c -L/usr/lib64/valgrind -lmpiwrap-amd64-linux -Xlinker -rpath=/usr/lib64/valgrind -o bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now all the bugs in the code are detected and reported&lt;br /&gt;
&lt;br /&gt;
 ==27774== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27774==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27774==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27774==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27774==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27773== Invalid write of size 4&lt;br /&gt;
 ==27773==    at 0x4026A0: main (bug.c:16)&lt;br /&gt;
 ==27773==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27774== Invalid write of size 4&lt;br /&gt;
 ==27774==    at 0x40271B: main (bug.c:23)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Suppression File ===&lt;br /&gt;
&lt;br /&gt;
There is also a valgrind suppression option &amp;lt;tt&amp;gt;--suppressions=&amp;quot;$(which mpirun | sed -e 's|/bin/.*|/share/openmpi/openmpi-valgrind.supp|')&amp;quot;&amp;lt;/tt&amp;gt;.  We have not observed any cases where this makes a difference yet though.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Package website&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.valgrind.org&lt;br /&gt;
&lt;br /&gt;
[[Category:Software packages]]&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11809</id>
		<title>VALGRIND</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11809"/>
				<updated>2015-09-08T19:38:23Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Missed version number change and various formatting cleanups&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=VALGRIND&lt;br /&gt;
|package_description=Memory debugger&lt;br /&gt;
|package_idnumber=132&lt;br /&gt;
}}&lt;br /&gt;
'''Valgrind''' is a powerful tool for analyzing programs, memory debugging, memory leak detection and profiling.  It is freely available under GNU license.  Version 3.5.0 is available on most SHARCNET systems.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' To avoid spurious warnings it is important to not use too new of a version of GCC or OpenMPI.  We recommend&lt;br /&gt;
&lt;br /&gt;
* gcc/4.8.2&lt;br /&gt;
* openmpi/gcc-debug/1.8.3 modules&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Valgrind is a dynamic binary instrumentation framework that dynamically translates executables to add instrumentation and track all memory and register usages by a program.  The advantages of this approach are that&lt;br /&gt;
&lt;br /&gt;
* it can be directly run on any executable, and&lt;br /&gt;
* dynamic translation allows ultimate instrumentation&lt;br /&gt;
&lt;br /&gt;
while the disadvantages are&lt;br /&gt;
&lt;br /&gt;
* 5-100 x slow down depending on tool,&lt;br /&gt;
* 12-18 x increase in size of translated code, and&lt;br /&gt;
* corner cases may exist between translated code and original.&lt;br /&gt;
&lt;br /&gt;
Several tools have been built upon this framework.  These include&lt;br /&gt;
&lt;br /&gt;
* ''memcheck'' -  memory error detector&lt;br /&gt;
* ''cachegrind'' - cache and branch-prediction profiler&lt;br /&gt;
* ''callgrind'' - call-graph generating cache and branch prediction profiler&lt;br /&gt;
* ''helgrind'' - thread error detector&lt;br /&gt;
* ''DRD'' - thread error detector&lt;br /&gt;
* ''Massif'' - heap profiler&lt;br /&gt;
* ''DHAT'' - dynamic heap analysis tool&lt;br /&gt;
* ''SGCheck'' - experimental stack and global array overrun detector&lt;br /&gt;
* ''BBV'' - experimental basic block vector generation tool&lt;br /&gt;
&lt;br /&gt;
You are welcome to use any or all of these, but we have only used ''memcheck'' and ''cachegrind'' and only support ''memcheck''.&lt;br /&gt;
&lt;br /&gt;
= Usage =&lt;br /&gt;
&lt;br /&gt;
The primary used tool is ''memcheck''.  This is the default tool and the only one we discuss here.  Documentation for other tools can be found on the [http://www.valgrind.org valgrind website].  The memcheck tool detects several common memory errors&lt;br /&gt;
&lt;br /&gt;
* overrunning and underrunning heap blocks,&lt;br /&gt;
* overrunning top of stack,&lt;br /&gt;
* continuing to access released memory,&lt;br /&gt;
* using uninitialized values,&lt;br /&gt;
* incorrectly using memory copying routines,&lt;br /&gt;
* incorrectly paired allocation/release calls,&lt;br /&gt;
* relasing unallocated memory, and&lt;br /&gt;
* not releasing memory.&lt;br /&gt;
&lt;br /&gt;
We recommend running all new code under valgrind on small test cases (small due to the aforementioned ~10x slowdown).  This can save hours and hours of debugging.  Running the program under valgrind can be as simple as compiling with debugging information (adding the &amp;lt;tt&amp;gt;-g&amp;lt;/tt&amp;gt; flag) and running as &amp;lt;tt&amp;gt;valgrind &amp;lt;program&amp;gt; &amp;lt;arguements&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Serial code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
&lt;br /&gt;
  // Execution depends on uninitialized value&lt;br /&gt;
  if (array[4] &amp;lt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is negative\n&amp;quot;);&lt;br /&gt;
  else if (array[4] == 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is zero\n&amp;quot;);&lt;br /&gt;
  else if (array[4] &amp;gt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is positive\n&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    printf(&amp;quot;the results are special\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug.  Running this under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reports this&lt;br /&gt;
&lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400511: main (bug.c:7)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x40052C: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400536: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400551: main (bug.c:11)&lt;br /&gt;
&lt;br /&gt;
Note that valgrind only reports uninitialized values usage once they lead to non-determinism (i.e., when the program encounters a branch whose choice depends on the result of an uninitiated value).  This means you the first report you get is frequently not in the calculation done on the uninitialized values but rather the convergence test or print statement at the end of calculations (print statements contains a bunch of branches in order to handling printing of each different digit).&lt;br /&gt;
&lt;br /&gt;
=== Tracking down uninitialized values ===&lt;br /&gt;
&lt;br /&gt;
More typically a program will be composed of multiple routines that all work on the data.  To this end, consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_sequence(double* array, const int array_length) {&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=1; i&amp;lt;array_length+1; ++i)&lt;br /&gt;
    array[i] = i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
  const int array_length = sizeof(array)/sizeof(array[0]);&lt;br /&gt;
&lt;br /&gt;
  double array_sum;&lt;br /&gt;
&lt;br /&gt;
  initialize_sequence(array,array_length);&lt;br /&gt;
  array_sum = sum(array,array_length);&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;the sum of 0..%d is %f\n&amp;quot;, array_length-1, array_sum);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has both indexing and uninitialized value bugs.  Despite this, directly running the code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will mostly likely produce the correct answer on most machines most of the time&lt;br /&gt;
&lt;br /&gt;
 the sum of 0..9 is 45.000000&lt;br /&gt;
&lt;br /&gt;
Running under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reliably gives many warnings of the following form&lt;br /&gt;
&lt;br /&gt;
 ==15930== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==15930==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x400722: main (bug.c:29)&lt;br /&gt;
&lt;br /&gt;
This is a typical numeric code example were the warnings first occur at a print statement because this is the first time the uninitialized value leads to non-determinism (i.e., the program's behaviour is random as it is taking or does not taking a branch based on a result computed from something that was not set by the programmer).&lt;br /&gt;
&lt;br /&gt;
We now know the problem is that something unset went into computing the value of ''array_sum'', so we should trace the ''array_sum'' calculation backwards through the program.  This quickly gets difficult as we then find ourselves also tracing back all variables that went into the ''array_sum'' calculation, and then all variables that went into those variables, and so on.&lt;br /&gt;
&lt;br /&gt;
Fortunately Valgrind provides a &amp;lt;tt&amp;gt;--track-origins=yes&amp;lt;/tt&amp;gt; flag to ease our search by telling us which variables are the source of the problem.  Re-running with this flag&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
valgrind --track-origins=yes ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gives warning messages augmented to include the source of the uninitialized value that went into the computation of ''array_sum''&lt;br /&gt;
&lt;br /&gt;
 ==17589== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==17589==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x400722: main (bug.c:29)&lt;br /&gt;
 ==17589==  Uninitialised value was created by a stack allocation&lt;br /&gt;
 ==17589==    at 0x400632: sum (bug.c:10)&lt;br /&gt;
&lt;br /&gt;
Now we know the source of the uninitialized value in the ''array_sum'' computation was a local variable in the ''sum'' routine.  Looking into ''sum'' we hopefully figure out without too much difficulty that we forgot to initialize ''array_sum'' to zero.  If our program is producing the correct answer, it is only because we are getting lucky and ''array_sum'' happens to be allocated from memory that is initially zero.&lt;br /&gt;
&lt;br /&gt;
Correcting the ''sum'' routine&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  array_sum = 0.0;&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and re-running under valgrind reveals we are still getting uninitialized values warnings associated with the ''array_sum'' computation.  Now (using the &amp;lt;tt&amp;gt;--track-origins=yes&amp;lt;/tt&amp;gt;) they are of the form&lt;br /&gt;
&lt;br /&gt;
 ==18613== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==18613==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x40072C: main (bug.c:30)&lt;br /&gt;
 ==18613==  Uninitialised value was created by a stack allocation&lt;br /&gt;
 ==18613==    at 0x400690: main (bug.c:21)&lt;br /&gt;
&lt;br /&gt;
Valgrind is now telling us that a local variable inside ''main'' went into the computation of ''array_sum'' despite never being set.  This must be ''array'' itself as ''array_length'' is clearly set to the compiler computed &amp;lt;tt&amp;gt;sizeof(array)/sizeof(array[0])&amp;lt;/tt&amp;gt; value.&lt;br /&gt;
&lt;br /&gt;
Looking at ''main'' it is clear ''array'' should have been fully initialized by ''initialize_sequence''.  Careful examination of this routine reveals the final error.  The initialization loop was done using Fortran indices (1...''array_length'')  instead of C (0...''array_length-1'').  Correcting this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
void initialize_sequence(double* array, const int array_length) {&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array[i] = i;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
finally produces code the runs under valgrind without any warnings.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' The Valgrind warnings were being generated because the ''array[0]'' value was not being initialized.  The code was also incorrect in that it was initializing ''array[array_length]'' which is one past the end of ''array''.  If you put this later error back into the program and run under Valgrind you will discover it does not produce any warnings.  This shows that even codes that successfully under Valgrind can still contain errors.&lt;br /&gt;
&lt;br /&gt;
=== Calling Valgrind from your program ===&lt;br /&gt;
&lt;br /&gt;
In some cases it can be helpful to call Valgrind directly from your program in order to check the status of various bits of memory.  This is easily done by including the ''valgrind/memcheck.h'' header file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;valgrind/memcheck.h&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and then adding calls to the appropriate [http://valgrind.org/docs/manual/mc-manual.html#mc-manual.clientreqs client check routines].  For example, here is a modified ''sum'' routine for the above program that prints a warning if it is called with an ''array'' that is not fully initialized&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  if (VALGRIND_CHECK_MEM_IS_DEFINED(array,sizeof(double)*array_length)) &lt;br /&gt;
    fprintf(stderr,&amp;quot;sum called with an array that is not fully defined...\n&amp;quot;); &lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the ''bug.c'' code under Valgrind with this modification produces the following output&lt;br /&gt;
&lt;br /&gt;
 ==29765== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==29765==    at 0x400745: sum (bug.c:15)&lt;br /&gt;
 ==29765==    by 0x400832: main (bug.c:31)&lt;br /&gt;
 ==29765==  Address 0x7fefff8e8 is on thread 1's stack&lt;br /&gt;
 ==29765== &lt;br /&gt;
 sum called with an array that is not fully defined...&lt;br /&gt;
&lt;br /&gt;
== MPI code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' MPI code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;mpi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc,char *argv[]){&lt;br /&gt;
  int rank, size;&lt;br /&gt;
  int value;&lt;br /&gt;
&lt;br /&gt;
  MPI_Init(&amp;amp;argc, &amp;amp;argv);&lt;br /&gt;
&lt;br /&gt;
  MPI_Comm_rank(MPI_COMM_WORLD, &amp;amp;rank);&lt;br /&gt;
  MPI_Comm_size(MPI_COMM_WORLD, &amp;amp;size);&lt;br /&gt;
&lt;br /&gt;
  if (rank == 0 &amp;amp;&amp;amp; size &amp;gt; 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Irecv(&amp;amp;value, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 0;&lt;br /&gt;
    MPI_Wait (&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  }&lt;br /&gt;
  else if (rank == 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Isend(&amp;amp;value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 1;&lt;br /&gt;
    MPI_Wait(&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  } &lt;br /&gt;
&lt;br /&gt;
  MPI_Finalize();&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug and two race condition bugs around the use of value.&lt;br /&gt;
&lt;br /&gt;
# The first race condition is that rank==0 sets value=0 while at the same time doing a non-blocking receive into value (bug:16).&lt;br /&gt;
# The uninitialized value problem is that rank==1 starts a send of value to rank==0 without ever setting value (bug:22).&lt;br /&gt;
# The second race condition is that rank==1 sets value=1 while at the same time doing a non-blocking send of value (bug:23).&lt;br /&gt;
&lt;br /&gt;
=== Basic Functionality ===&lt;br /&gt;
&lt;br /&gt;
If we just straight up compile and run this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load gcc/4.8.2 openmpi/gcc/1.8.3&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we presumably get a report about the uninitialized value, but it is buried in tens of thousands of other bogus error messages.&lt;br /&gt;
&lt;br /&gt;
This solution is to link against the valgrind openmpi debug wrapper library too&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpicc -Wall -g bug.c -L/usr/lib64/valgrind -lmpiwrap-amd64-linux -Xlinker -rpath=/usr/lib64/valgrind -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now there are only a few bogus errors reported of the form&lt;br /&gt;
&lt;br /&gt;
 ==12598== Syscall param write(buf) points to uninitialised byte(s)&lt;br /&gt;
 ==12598==    at 0x53916FD: ??? (in /lib64/libpthread-2.12.so)&lt;br /&gt;
 ==12598==    by 0x8AC8E40: send_bytes (oob_tcp_sendrecv.c:84)&lt;br /&gt;
 ==12598==    by 0x8AC9471: mca_oob_tcp_send_handler (oob_tcp_sendrecv.c:205)&lt;br /&gt;
 ==12598==    by 0x616FA23: opal_libevent2021_event_base_loop (in /opt/sharcnet/openmpi/1.8.1/gcc-debug/lib/libopen-pal.so.6.1.1)&lt;br /&gt;
 ==12598==    by 0x5B7E78D: orte_progress_thread_engine (ess_base_std_app.c:456)&lt;br /&gt;
 ==12598==    by 0x538A9D0: start_thread (in /lib64/libpthread-2.12.so)&lt;br /&gt;
 ==12598==    by 0x8AB86FF: ???&lt;br /&gt;
&lt;br /&gt;
We know this isn't an issue with ''bug.c'' as the backtrace shows it is occurring in a pure OpenMPI thread (the backtrace starts with ''start_thread'' and all subsequent routines are not from ''bug.c'').  Skipping over these we now see Valgrind is picking up on sending the uninitialized value&lt;br /&gt;
&lt;br /&gt;
 ==12599== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==12599==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==12599==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==12599==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==12599==    by 0x400B02: main (bug.c:22)&lt;br /&gt;
 ==12599==  Address 0x7fefff5c4 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' If we want to avoid recompiling our program, we can also preload the ''mpiwrap-amd64-linux'' library instead of linking against it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
LD_LIBRARY_PATH=&amp;quot;$(which mpirun | sed -e 's|/bin/.*$|/lib|')${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}&amp;quot; \&lt;br /&gt;
LD_PRELOAD=/usr/lib64/valgrind/libmpiwrap-amd64-linux.so mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Advanced Functionality ===&lt;br /&gt;
&lt;br /&gt;
Now, if on top of this, we also bring in the valgrind enabled openmpi debug library, things get really sweet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload gcc openmpi&lt;br /&gt;
module load gcc/4.8.2 openmpi/gcc-debug/1.8.3&lt;br /&gt;
mpicc -Wall -g bug.c -L/usr/lib64/valgrind -lmpiwrap-amd64-linux -Xlinker -rpath=/usr/lib64/valgrind -o bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now all the bugs in the code are detected and reported&lt;br /&gt;
&lt;br /&gt;
 ==27774== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27774==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27774==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27774==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27774==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27773== Invalid write of size 4&lt;br /&gt;
 ==27773==    at 0x4026A0: main (bug.c:16)&lt;br /&gt;
 ==27773==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27774== Invalid write of size 4&lt;br /&gt;
 ==27774==    at 0x40271B: main (bug.c:23)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Suppression File ===&lt;br /&gt;
&lt;br /&gt;
There is also a valgrind suppression option &amp;lt;tt&amp;gt;--suppressions=&amp;quot;$(which mpirun | sed -e 's|/bin/.*|/share/openmpi/openmpi-valgrind.supp|')&amp;quot;&amp;lt;/tt&amp;gt;.  We have not observed any cases where this makes a difference yet though.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Package website&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.valgrind.org&lt;br /&gt;
&lt;br /&gt;
[[Category:Software packages]]&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11808</id>
		<title>VALGRIND</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11808"/>
				<updated>2015-09-08T19:34:50Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Update MPI section for recommended GCC and OpenMPI versions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=VALGRIND&lt;br /&gt;
|package_description=Memory debugger&lt;br /&gt;
|package_idnumber=132&lt;br /&gt;
}}&lt;br /&gt;
'''Valgrind''' is a powerful tool for analyzing programs, memory debugging, memory leak detection and profiling.  It is freely available under GNU license.  Version 3.5.0 is available on most SHARCNET systems.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' To avoid spurious warnings it is important to not use too new of a version of GCC or OpenMPI.  We recommend&lt;br /&gt;
&lt;br /&gt;
* gcc/4.8.2&lt;br /&gt;
* openmpi/gcc-debug/1.8.1 modules&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Valgrind is a dynamic binary instrumentation framework that dynamically translates executables to add instrumentation and track all memory and register usages by a program.  The advantages of this approach are that&lt;br /&gt;
&lt;br /&gt;
* it can be directly run on any executable, and&lt;br /&gt;
* dynamic translation allows ultimate instrumentation&lt;br /&gt;
&lt;br /&gt;
while the disadvantages are&lt;br /&gt;
&lt;br /&gt;
* 5-100 x slow down depending on tool,&lt;br /&gt;
* 12-18 x increase in size of translated code, and&lt;br /&gt;
* corner cases may exist between translated code and original.&lt;br /&gt;
&lt;br /&gt;
Several tools have been built upon this framework.  These include&lt;br /&gt;
&lt;br /&gt;
* ''memcheck'' -  memory error detector&lt;br /&gt;
* ''cachegrind'' - cache and branch-prediction profiler&lt;br /&gt;
* ''callgrind'' - call-graph generating cache and branch prediction profiler&lt;br /&gt;
* ''helgrind'' - thread error detector&lt;br /&gt;
* ''DRD'' - thread error detector&lt;br /&gt;
* ''Massif'' - heap profiler&lt;br /&gt;
* ''DHAT'' - dynamic heap analysis tool&lt;br /&gt;
* ''SGCheck'' - experimental stack and global array overrun detector&lt;br /&gt;
* ''BBV'' - experimental basic block vector generation tool&lt;br /&gt;
&lt;br /&gt;
You are welcome to use any or all of these, but we have only used ''memcheck'' and ''cachegrind'' and only support ''memcheck''.&lt;br /&gt;
&lt;br /&gt;
= Usage =&lt;br /&gt;
&lt;br /&gt;
The primary used tool is ''memcheck''.  This is the default tool and the only one we discuss here.  Documentation for other tools can be found on the [http://www.valgrind.org valgrind website].  The memcheck tool detects several common memory errors&lt;br /&gt;
&lt;br /&gt;
* overrunning and underrunning heap blocks,&lt;br /&gt;
* overrunning top of stack,&lt;br /&gt;
* continuing to access released memory,&lt;br /&gt;
* using uninitialized values,&lt;br /&gt;
* incorrectly using memory copying routines,&lt;br /&gt;
* incorrectly paired allocation/release calls,&lt;br /&gt;
* relasing unallocated memory, and&lt;br /&gt;
* not releasing memory.&lt;br /&gt;
&lt;br /&gt;
We recommend running all new code under valgrind on small test cases (small due to the aforementioned ~10x slowdown).  This can save hours and hours of debugging.  Running the program under valgrind can be as simple as compiling with debugging information (adding the &amp;lt;tt&amp;gt;-g&amp;lt;/tt&amp;gt; flag) and running as &amp;lt;tt&amp;gt;valgrind &amp;lt;program&amp;gt; &amp;lt;arguements&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Serial code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
&lt;br /&gt;
  // Execution depends on uninitialized value&lt;br /&gt;
  if (array[4] &amp;lt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is negative\n&amp;quot;);&lt;br /&gt;
  else if (array[4] == 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is zero\n&amp;quot;);&lt;br /&gt;
  else if (array[4] &amp;gt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is positive\n&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    printf(&amp;quot;the results are special\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug.  Running this under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reports this&lt;br /&gt;
&lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400511: main (bug.c:7)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x40052C: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400536: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400551: main (bug.c:11)&lt;br /&gt;
&lt;br /&gt;
Note that valgrind only reports uninitialized values usage once they lead to non-determinism (i.e., when the program encounters a branch whose choice depends on the result of an uninitiated value).  This means you the first report you get is frequently not in the calculation done on the uninitialized values but rather the convergence test or print statement at the end of calculations (print statements contains a bunch of branches in order to handling printing of each different digit).&lt;br /&gt;
&lt;br /&gt;
=== Tracking down uninitialized values ===&lt;br /&gt;
&lt;br /&gt;
More typically a program will be composed of multiple routines that all work on the data.  To this end, consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_sequence(double* array, const int array_length) {&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=1; i&amp;lt;array_length+1; ++i)&lt;br /&gt;
    array[i] = i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
  const int array_length = sizeof(array)/sizeof(array[0]);&lt;br /&gt;
&lt;br /&gt;
  double array_sum;&lt;br /&gt;
&lt;br /&gt;
  initialize_sequence(array,array_length);&lt;br /&gt;
  array_sum = sum(array,array_length);&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;the sum of 0..%d is %f\n&amp;quot;, array_length-1, array_sum);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has both indexing and uninitialized value bugs.  Despite this, directly running the code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will mostly likely produce the correct answer on most machines most of the time&lt;br /&gt;
&lt;br /&gt;
 the sum of 0..9 is 45.000000&lt;br /&gt;
&lt;br /&gt;
Running under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reliably gives many warnings of the following form&lt;br /&gt;
&lt;br /&gt;
 ==15930== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==15930==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x400722: main (bug.c:29)&lt;br /&gt;
&lt;br /&gt;
This is a typical numeric code example were the warnings first occur at a print statement because this is the first time the uninitialized value leads to non-determinism (i.e., the program's behaviour is random as it is taking or does not taking a branch based on a result computed from something that was not set by the programmer).&lt;br /&gt;
&lt;br /&gt;
We now know the problem is that something unset went into computing the value of ''array_sum'', so we should trace the ''array_sum'' calculation backwards through the program.  This quickly gets difficult as we then find ourselves also tracing back all variables that went into the ''array_sum'' calculation, and then all variables that went into those variables, and so on.&lt;br /&gt;
&lt;br /&gt;
Fortunately Valgrind provides a ''--track-origins=yes'' flag to ease our search by telling us which variables are the source of the problem.  Re-running with this flag&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
valgrind --track-origins=yes ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gives warning messages augmented to include the source of the uninitialized value that went into the computation of ''array_sum''&lt;br /&gt;
&lt;br /&gt;
 ==17589== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==17589==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x400722: main (bug.c:29)&lt;br /&gt;
 ==17589==  Uninitialised value was created by a stack allocation&lt;br /&gt;
 ==17589==    at 0x400632: sum (bug.c:10)&lt;br /&gt;
&lt;br /&gt;
Now we know the source of the uninitialized value in the ''array_sum'' computation was a local variable in the ''sum'' routine.  Looking into ''sum'' we hopefully figure out without too much difficulty that we forgot to initialize ''array_sum'' to zero.  If our program is producing the correct answer, it is only because we are getting lucky and ''array_sum'' happens to be allocated from memory that is initially zero.&lt;br /&gt;
&lt;br /&gt;
Correcting the ''sum'' routine&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  array_sum = 0.0;&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and re-running under valgrind reveals we are still getting uninitialized values warnings associated with the ''array_sum'' computation.  Now (using the ''--track-origins=yes'') they are of the form&lt;br /&gt;
&lt;br /&gt;
 ==18613== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==18613==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x40072C: main (bug.c:30)&lt;br /&gt;
 ==18613==  Uninitialised value was created by a stack allocation&lt;br /&gt;
 ==18613==    at 0x400690: main (bug.c:21)&lt;br /&gt;
&lt;br /&gt;
Valgrind is now telling us that a local variable inside ''main'' went into the computation of ''array_sum'' despite never being set.  This must be ''array'' itself as ''array_length'' is clearly set to the compiler computed ''sizeof(array)/sizeof(array[0])'' value.&lt;br /&gt;
&lt;br /&gt;
Looking at ''main'' it is clear ''array'' should have been fully initialized by ''initialize_sequence''.  Careful examination of this routine reveals the final error.  The initialization loop was done using Fortran indices (1...''array_length'')  instead of C (0...''array_length-1'').  Correcting this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
void initialize_sequence(double* array, const int array_length) {&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array[i] = i;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
finally produces code the runs under valgrind without any warnings.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' The Valgrind warnings were being generated because the ''array[0]'' value was not being initialized.  The code was also incorrect in that it was initializing ''array[array_length]'' which is one past the end of ''array''.  If you put this later error back into the program and run under Valgrind you will discover it does not produce any warnings.  This shows that even codes that successfully under Valgrind can still contain errors.&lt;br /&gt;
&lt;br /&gt;
=== Calling Valgrind from your program ===&lt;br /&gt;
&lt;br /&gt;
In some cases it can be helpful to call Valgrind directly from your program in order to check the status of various bits of memory.  This is easily done by including the ''valgrind/memcheck.h'' header file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;valgrind/memcheck.h&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and then adding calls to the appropriate [http://valgrind.org/docs/manual/mc-manual.html#mc-manual.clientreqs client check routines].  For example, here is a modified ''sum'' routine for the above program that prints a warning if it is called with an ''array'' that is not fully initialized&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  if (VALGRIND_CHECK_MEM_IS_DEFINED(array,sizeof(double)*array_length)) &lt;br /&gt;
    fprintf(stderr,&amp;quot;sum called with an array that is not fully defined...\n&amp;quot;); &lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the ''bug.c'' code under Valgrind with this modification produces the following output&lt;br /&gt;
&lt;br /&gt;
 ==29765== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==29765==    at 0x400745: sum (bug.c:15)&lt;br /&gt;
 ==29765==    by 0x400832: main (bug.c:31)&lt;br /&gt;
 ==29765==  Address 0x7fefff8e8 is on thread 1's stack&lt;br /&gt;
 ==29765== &lt;br /&gt;
 sum called with an array that is not fully defined...&lt;br /&gt;
&lt;br /&gt;
== MPI code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' MPI code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;mpi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc,char *argv[]){&lt;br /&gt;
  int rank, size;&lt;br /&gt;
  int value;&lt;br /&gt;
&lt;br /&gt;
  MPI_Init(&amp;amp;argc, &amp;amp;argv);&lt;br /&gt;
&lt;br /&gt;
  MPI_Comm_rank(MPI_COMM_WORLD, &amp;amp;rank);&lt;br /&gt;
  MPI_Comm_size(MPI_COMM_WORLD, &amp;amp;size);&lt;br /&gt;
&lt;br /&gt;
  if (rank == 0 &amp;amp;&amp;amp; size &amp;gt; 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Irecv(&amp;amp;value, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 0;&lt;br /&gt;
    MPI_Wait (&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  }&lt;br /&gt;
  else if (rank == 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Isend(&amp;amp;value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 1;&lt;br /&gt;
    MPI_Wait(&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  } &lt;br /&gt;
&lt;br /&gt;
  MPI_Finalize();&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug and two race condition bugs around the use of value.&lt;br /&gt;
&lt;br /&gt;
# The first race condition is that rank==0 sets value=0 while at the same time doing a non-blocking receive into value (bug:16).&lt;br /&gt;
# The uninitialized value problem is that rank==1 starts a send of value to rank==0 without ever setting value (bug:22).&lt;br /&gt;
# The second race condition is that rank==1 sets value=1 while at the same time doing a non-blocking send of value (bug:23).&lt;br /&gt;
&lt;br /&gt;
=== Basic Functionality ===&lt;br /&gt;
&lt;br /&gt;
If we just straight up compile and run this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load gcc/4.8.2 openmpi/gcc/1.8.3&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we presumably get a report about the uninitialized value, but it is buried in tens of thousands of other bogus error messages.&lt;br /&gt;
&lt;br /&gt;
This solution is to link against the valgrind openmpi debug wrapper library too&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpicc -Wall -g bug.c -L/usr/lib64/valgrind -lmpiwrap-amd64-linux -Xlinker -rpath=/usr/lib64/valgrind -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now there are only a few bogus errors reported of the form&lt;br /&gt;
&lt;br /&gt;
 ==12598== Syscall param write(buf) points to uninitialised byte(s)&lt;br /&gt;
 ==12598==    at 0x53916FD: ??? (in /lib64/libpthread-2.12.so)&lt;br /&gt;
 ==12598==    by 0x8AC8E40: send_bytes (oob_tcp_sendrecv.c:84)&lt;br /&gt;
 ==12598==    by 0x8AC9471: mca_oob_tcp_send_handler (oob_tcp_sendrecv.c:205)&lt;br /&gt;
 ==12598==    by 0x616FA23: opal_libevent2021_event_base_loop (in /opt/sharcnet/openmpi/1.8.1/gcc-debug/lib/libopen-pal.so.6.1.1)&lt;br /&gt;
 ==12598==    by 0x5B7E78D: orte_progress_thread_engine (ess_base_std_app.c:456)&lt;br /&gt;
 ==12598==    by 0x538A9D0: start_thread (in /lib64/libpthread-2.12.so)&lt;br /&gt;
 ==12598==    by 0x8AB86FF: ???&lt;br /&gt;
&lt;br /&gt;
We know this isn't an issue with ''bug.c'' as the backtrace shows it is occurring in a pure OpenMPI thread (the backtrace starts with ''start_thread'' and all subsequent routines are not from ''bug.c'').  Skipping over these we now see Valgrind is picking up on sending the uninitialized value&lt;br /&gt;
&lt;br /&gt;
 ==12599== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==12599==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==12599==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==12599==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==12599==    by 0x400B02: main (bug.c:22)&lt;br /&gt;
 ==12599==  Address 0x7fefff5c4 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' If we want to avoid recompiling our program, we can also preload the ''mpiwrap-amd64-linux'' library instead of linking against it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
LD_LIBRARY_PATH=&amp;quot;$(which mpirun | sed -e 's|/bin/.*$|/lib|')${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}&amp;quot; \&lt;br /&gt;
LD_PRELOAD=/usr/lib64/valgrind/libmpiwrap-amd64-linux.so mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Advanced Functionality ===&lt;br /&gt;
&lt;br /&gt;
Now, if on top of this, we also bring in the valgrind enabled openmpi debug library, things get really sweet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload gcc openmpi&lt;br /&gt;
module load gcc/4.8.2 openmpi/gcc-debug/1.8.3&lt;br /&gt;
mpicc -Wall -g bug.c -L/usr/lib64/valgrind -lmpiwrap-amd64-linux -Xlinker -rpath=/usr/lib64/valgrind -o bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now all the bugs in the code are detected and reported&lt;br /&gt;
&lt;br /&gt;
 ==27774== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27774==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27774==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27774==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27774==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27773== Invalid write of size 4&lt;br /&gt;
 ==27773==    at 0x4026A0: main (bug.c:16)&lt;br /&gt;
 ==27773==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27774== Invalid write of size 4&lt;br /&gt;
 ==27774==    at 0x40271B: main (bug.c:23)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Suppression File ===&lt;br /&gt;
&lt;br /&gt;
There is also a valgrind suppression option &amp;lt;tt&amp;gt;--suppressions=&amp;quot;$(which mpirun | sed -e 's|/bin/.*|/share/openmpi/openmpi-valgrind.supp|')&amp;quot;&amp;lt;/tt&amp;gt;, however we have not observed any cases where this makes a difference yet.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Package website&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.valgrind.org&lt;br /&gt;
&lt;br /&gt;
[[Category:Software packages]]&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11792</id>
		<title>VALGRIND</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11792"/>
				<updated>2015-09-08T18:03:09Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Minor correction&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=VALGRIND&lt;br /&gt;
|package_description=Memory debugger&lt;br /&gt;
|package_idnumber=132&lt;br /&gt;
}}&lt;br /&gt;
'''Valgrind''' is a powerful tool for analyzing programs, memory debugging, memory leak detection and profiling.  It is freely available under GNU license.  Version 3.5.0 is available on most SHARCNET systems.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' To avoid spurious warnings it is important to not use too new of a version of GCC or OpenMPI.  We recommend&lt;br /&gt;
&lt;br /&gt;
* gcc/4.8.2&lt;br /&gt;
* openmpi/gcc-debug/1.8.1 modules&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Valgrind is a dynamic binary instrumentation framework that dynamically translates executables to add instrumentation and track all memory and register usages by a program.  The advantages of this approach are that&lt;br /&gt;
&lt;br /&gt;
* it can be directly run on any executable, and&lt;br /&gt;
* dynamic translation allows ultimate instrumentation&lt;br /&gt;
&lt;br /&gt;
while the disadvantages are&lt;br /&gt;
&lt;br /&gt;
* 5-100 x slow down depending on tool,&lt;br /&gt;
* 12-18 x increase in size of translated code, and&lt;br /&gt;
* corner cases may exist between translated code and original.&lt;br /&gt;
&lt;br /&gt;
Several tools have been built upon this framework.  These include&lt;br /&gt;
&lt;br /&gt;
* ''memcheck'' -  memory error detector&lt;br /&gt;
* ''cachegrind'' - cache and branch-prediction profiler&lt;br /&gt;
* ''callgrind'' - call-graph generating cache and branch prediction profiler&lt;br /&gt;
* ''helgrind'' - thread error detector&lt;br /&gt;
* ''DRD'' - thread error detector&lt;br /&gt;
* ''Massif'' - heap profiler&lt;br /&gt;
* ''DHAT'' - dynamic heap analysis tool&lt;br /&gt;
* ''SGCheck'' - experimental stack and global array overrun detector&lt;br /&gt;
* ''BBV'' - experimental basic block vector generation tool&lt;br /&gt;
&lt;br /&gt;
You are welcome to use any or all of these, but we have only used ''memcheck'' and ''cachegrind'' and only support ''memcheck''.&lt;br /&gt;
&lt;br /&gt;
= Usage =&lt;br /&gt;
&lt;br /&gt;
The primary used tool is ''memcheck''.  This is the default tool and the only one we discuss here.  Documentation for other tools can be found on the [http://www.valgrind.org valgrind website].  The memcheck tool detects several common memory errors&lt;br /&gt;
&lt;br /&gt;
* overrunning and underrunning heap blocks,&lt;br /&gt;
* overrunning top of stack,&lt;br /&gt;
* continuing to access released memory,&lt;br /&gt;
* using uninitialized values,&lt;br /&gt;
* incorrectly using memory copying routines,&lt;br /&gt;
* incorrectly paired allocation/release calls,&lt;br /&gt;
* relasing unallocated memory, and&lt;br /&gt;
* not releasing memory.&lt;br /&gt;
&lt;br /&gt;
We recommend running all new code under valgrind on small test cases (small due to the aforementioned ~10x slowdown).  This can save hours and hours of debugging.  Running the program under valgrind can be as simple as compiling with debugging information (adding the &amp;lt;tt&amp;gt;-g&amp;lt;/tt&amp;gt; flag) and running as &amp;lt;tt&amp;gt;valgrind &amp;lt;program&amp;gt; &amp;lt;arguements&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Serial code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
&lt;br /&gt;
  // Execution depends on uninitialized value&lt;br /&gt;
  if (array[4] &amp;lt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is negative\n&amp;quot;);&lt;br /&gt;
  else if (array[4] == 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is zero\n&amp;quot;);&lt;br /&gt;
  else if (array[4] &amp;gt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is positive\n&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    printf(&amp;quot;the results are special\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug.  Running this under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reports this&lt;br /&gt;
&lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400511: main (bug.c:7)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x40052C: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400536: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400551: main (bug.c:11)&lt;br /&gt;
&lt;br /&gt;
Note that valgrind only reports uninitialized values usage once they lead to non-determinism (i.e., when the program encounters a branch whose choice depends on the result of an uninitiated value).  This means you the first report you get is frequently not in the calculation done on the uninitialized values but rather the convergence test or print statement at the end of calculations (print statements contains a bunch of branches in order to handling printing of each different digit).&lt;br /&gt;
&lt;br /&gt;
=== Tracking down uninitialized values ===&lt;br /&gt;
&lt;br /&gt;
More typically a program will be composed of multiple routines that all work on the data.  To this end, consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_sequence(double* array, const int array_length) {&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=1; i&amp;lt;array_length+1; ++i)&lt;br /&gt;
    array[i] = i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
  const int array_length = sizeof(array)/sizeof(array[0]);&lt;br /&gt;
&lt;br /&gt;
  double array_sum;&lt;br /&gt;
&lt;br /&gt;
  initialize_sequence(array,array_length);&lt;br /&gt;
  array_sum = sum(array,array_length);&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;the sum of 0..%d is %f\n&amp;quot;, array_length-1, array_sum);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has both indexing and uninitialized value bugs.  Despite this, directly running the code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will mostly likely produce the correct answer on most machines most of the time&lt;br /&gt;
&lt;br /&gt;
 the sum of 0..9 is 45.000000&lt;br /&gt;
&lt;br /&gt;
Running under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reliably gives many warnings of the following form&lt;br /&gt;
&lt;br /&gt;
 ==15930== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==15930==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x400722: main (bug.c:29)&lt;br /&gt;
&lt;br /&gt;
This is a typical numeric code example were the warnings first occur at a print statement because this is the first time the uninitialized value leads to non-determinism (i.e., the program's behaviour is random as it is taking or does not taking a branch based on a result computed from something that was not set by the programmer).&lt;br /&gt;
&lt;br /&gt;
We now know the problem is that something unset went into computing the value of ''array_sum'', so we should trace the ''array_sum'' calculation backwards through the program.  This quickly gets difficult as we then find ourselves also tracing back all variables that went into the ''array_sum'' calculation, and then all variables that went into those variables, and so on.&lt;br /&gt;
&lt;br /&gt;
Fortunately Valgrind provides a ''--track-origins=yes'' flag to ease our search by telling us which variables are the source of the problem.  Re-running with this flag&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
valgrind --track-origins=yes ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gives warning messages augmented to include the source of the uninitialized value that went into the computation of ''array_sum''&lt;br /&gt;
&lt;br /&gt;
 ==17589== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==17589==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x400722: main (bug.c:29)&lt;br /&gt;
 ==17589==  Uninitialised value was created by a stack allocation&lt;br /&gt;
 ==17589==    at 0x400632: sum (bug.c:10)&lt;br /&gt;
&lt;br /&gt;
Now we know the source of the uninitialized value in the ''array_sum'' computation was a local variable in the ''sum'' routine.  Looking into ''sum'' we hopefully figure out without too much difficulty that we forgot to initialize ''array_sum'' to zero.  If our program is producing the correct answer, it is only because we are getting lucky and ''array_sum'' happens to be allocated from memory that is initially zero.&lt;br /&gt;
&lt;br /&gt;
Correcting the ''sum'' routine&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  array_sum = 0.0;&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and re-running under valgrind reveals we are still getting uninitialized values warnings associated with the ''array_sum'' computation.  Now (using the ''--track-origins=yes'') they are of the form&lt;br /&gt;
&lt;br /&gt;
 ==18613== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==18613==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x40072C: main (bug.c:30)&lt;br /&gt;
 ==18613==  Uninitialised value was created by a stack allocation&lt;br /&gt;
 ==18613==    at 0x400690: main (bug.c:21)&lt;br /&gt;
&lt;br /&gt;
Valgrind is now telling us that a local variable inside ''main'' went into the computation of ''array_sum'' despite never being set.  This must be ''array'' itself as ''array_length'' is clearly set to the compiler computed ''sizeof(array)/sizeof(array[0])'' value.&lt;br /&gt;
&lt;br /&gt;
Looking at ''main'' it is clear ''array'' should have been fully initialized by ''initialize_sequence''.  Careful examination of this routine reveals the final error.  The initialization loop was done using Fortran indices (1...''array_length'')  instead of C (0...''array_length-1'').  Correcting this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
void initialize_sequence(double* array, const int array_length) {&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array[i] = i;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
finally produces code the runs under valgrind without any warnings.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' The Valgrind warnings were being generated because the ''array[0]'' value was not being initialized.  The code was also incorrect in that it was initializing ''array[array_length]'' which is one past the end of ''array''.  If you put this later error back into the program and run under Valgrind you will discover it does not produce any warnings.  This shows that even codes that successfully under Valgrind can still contain errors.&lt;br /&gt;
&lt;br /&gt;
=== Calling Valgrind from your program ===&lt;br /&gt;
&lt;br /&gt;
In some cases it can be helpful to call Valgrind directly from your program in order to check the status of various bits of memory.  This is easily done by including the ''valgrind/memcheck.h'' header file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;valgrind/memcheck.h&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and then adding calls to the appropriate [http://valgrind.org/docs/manual/mc-manual.html#mc-manual.clientreqs client check routines].  For example, here is a modified ''sum'' routine for the above program that prints a warning if it is called with an ''array'' that is not fully initialized&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  if (VALGRIND_CHECK_MEM_IS_DEFINED(array,sizeof(double)*array_length)) &lt;br /&gt;
    fprintf(stderr,&amp;quot;sum called with an array that is not fully defined...\n&amp;quot;); &lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the ''bug.c'' code under Valgrind with this modification produces the following output&lt;br /&gt;
&lt;br /&gt;
 ==29765== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==29765==    at 0x400745: sum (bug.c:15)&lt;br /&gt;
 ==29765==    by 0x400832: main (bug.c:31)&lt;br /&gt;
 ==29765==  Address 0x7fefff8e8 is on thread 1's stack&lt;br /&gt;
 ==29765== &lt;br /&gt;
 sum called with an array that is not fully defined...&lt;br /&gt;
&lt;br /&gt;
== MPI code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' MPI code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;mpi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc,char *argv[]){&lt;br /&gt;
  int rank, size;&lt;br /&gt;
  int value;&lt;br /&gt;
&lt;br /&gt;
  MPI_Init(&amp;amp;argc, &amp;amp;argv);&lt;br /&gt;
&lt;br /&gt;
  MPI_Comm_rank(MPI_COMM_WORLD, &amp;amp;rank);&lt;br /&gt;
  MPI_Comm_size(MPI_COMM_WORLD, &amp;amp;size);&lt;br /&gt;
&lt;br /&gt;
  if (rank == 0 &amp;amp;&amp;amp; size &amp;gt; 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Irecv(&amp;amp;value, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 0;&lt;br /&gt;
    MPI_Wait (&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  }&lt;br /&gt;
  else if (rank == 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Isend(&amp;amp;value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 1;&lt;br /&gt;
    MPI_Wait(&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  } &lt;br /&gt;
&lt;br /&gt;
  MPI_Finalize();&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug and two race condition bugs around the use of value.&lt;br /&gt;
&lt;br /&gt;
# The first race condition is that rank==0 sets value=0 while at the same time doing a non-blocking receive into value (bug:16).&lt;br /&gt;
# The uninitialized value problem is that rank==1 starts a send of value to rank==0 without ever setting value (bug:22).&lt;br /&gt;
# The second race condition is that rank==1 sets value=1 while at the same time doing a non-blocking send of value (bug:23).&lt;br /&gt;
&lt;br /&gt;
=== Basic Functionality ===&lt;br /&gt;
&lt;br /&gt;
If you run this using the non-debug/valgrind openmpi valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load intel/12.1.3 openmpi/intel/1.6.2&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you are presumably getting a report about the uninitialized value, but it is burried in 55517 other bogus error messages.&lt;br /&gt;
&lt;br /&gt;
This solution to this is to link against the valgrind openmpi debug wrapper library too.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpicc -Wall -g bug.c -L/usr/lib64/valgrind -lmpiwrap-amd64-linux -Xlinker -rpath=/usr/lib64/valgrind -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This now only reports one bogus error (a free on exit) and picks up the sending of the uninitialized value&lt;br /&gt;
&lt;br /&gt;
 ==27638== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27638==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27638==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27638==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27638==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27638==  Address 0x7fefff734 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Advanced Functionality ===&lt;br /&gt;
&lt;br /&gt;
Now, if on top of this, you also bring in the valgrind enabled openmpi debug library, things get really sweet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load intel/12.1.3 openmpi/intel-debug/1.6.2&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
LD_PRELOAD=/usr/lib64/valgrind/libmpiwrap-amd64-linux.so mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You still only get one bogus error (a free on exit) and all the bugs in the code are detected and reported&lt;br /&gt;
&lt;br /&gt;
 ==27774== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27774==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27774==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27774==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27774==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27773== Invalid write of size 4&lt;br /&gt;
 ==27773==    at 0x4026A0: main (bug.c:16)&lt;br /&gt;
 ==27773==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27774== Invalid write of size 4&lt;br /&gt;
 ==27774==    at 0x40271B: main (bug.c:23)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Suppression File ===&lt;br /&gt;
&lt;br /&gt;
There is also a valgrind suppression option &amp;lt;tt&amp;gt;--suppressions=/opt/sharcnet/openmpi/1.6.2/intel-debug/share/openmpi/openmpi-valgrind.supp&amp;lt;/tt&amp;gt;, however we have not observed any cases where this makes a difference yet.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Package website&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.valgrind.org&lt;br /&gt;
&lt;br /&gt;
[[Category:Software packages]]&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11791</id>
		<title>VALGRIND</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11791"/>
				<updated>2015-09-08T18:02:44Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Add section about using client API&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=VALGRIND&lt;br /&gt;
|package_description=Memory debugger&lt;br /&gt;
|package_idnumber=132&lt;br /&gt;
}}&lt;br /&gt;
'''Valgrind''' is a powerful tool for analyzing programs, memory debugging, memory leak detection and profiling.  It is freely available under GNU license.  Version 3.5.0 is available on most SHARCNET systems.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' To avoid spurious warnings it is important to not use too new of a version of GCC or OpenMPI.  We recommend&lt;br /&gt;
&lt;br /&gt;
* gcc/4.8.2&lt;br /&gt;
* openmpi/gcc-debug/1.8.1 modules&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Valgrind is a dynamic binary instrumentation framework that dynamically translates executables to add instrumentation and track all memory and register usages by a program.  The advantages of this approach are that&lt;br /&gt;
&lt;br /&gt;
* it can be directly run on any executable, and&lt;br /&gt;
* dynamic translation allows ultimate instrumentation&lt;br /&gt;
&lt;br /&gt;
while the disadvantages are&lt;br /&gt;
&lt;br /&gt;
* 5-100 x slow down depending on tool,&lt;br /&gt;
* 12-18 x increase in size of translated code, and&lt;br /&gt;
* corner cases may exist between translated code and original.&lt;br /&gt;
&lt;br /&gt;
Several tools have been built upon this framework.  These include&lt;br /&gt;
&lt;br /&gt;
* ''memcheck'' -  memory error detector&lt;br /&gt;
* ''cachegrind'' - cache and branch-prediction profiler&lt;br /&gt;
* ''callgrind'' - call-graph generating cache and branch prediction profiler&lt;br /&gt;
* ''helgrind'' - thread error detector&lt;br /&gt;
* ''DRD'' - thread error detector&lt;br /&gt;
* ''Massif'' - heap profiler&lt;br /&gt;
* ''DHAT'' - dynamic heap analysis tool&lt;br /&gt;
* ''SGCheck'' - experimental stack and global array overrun detector&lt;br /&gt;
* ''BBV'' - experimental basic block vector generation tool&lt;br /&gt;
&lt;br /&gt;
You are welcome to use any or all of these, but we have only used ''memcheck'' and ''cachegrind'' and only support ''memcheck''.&lt;br /&gt;
&lt;br /&gt;
= Usage =&lt;br /&gt;
&lt;br /&gt;
The primary used tool is ''memcheck''.  This is the default tool and the only one we discuss here.  Documentation for other tools can be found on the [http://www.valgrind.org valgrind website].  The memcheck tool detects several common memory errors&lt;br /&gt;
&lt;br /&gt;
* overrunning and underrunning heap blocks,&lt;br /&gt;
* overrunning top of stack,&lt;br /&gt;
* continuing to access released memory,&lt;br /&gt;
* using uninitialized values,&lt;br /&gt;
* incorrectly using memory copying routines,&lt;br /&gt;
* incorrectly paired allocation/release calls,&lt;br /&gt;
* relasing unallocated memory, and&lt;br /&gt;
* not releasing memory.&lt;br /&gt;
&lt;br /&gt;
We recommend running all new code under valgrind on small test cases (small due to the aforementioned ~10x slowdown).  This can save hours and hours of debugging.  Running the program under valgrind can be as simple as compiling with debugging information (adding the &amp;lt;tt&amp;gt;-g&amp;lt;/tt&amp;gt; flag) and running as &amp;lt;tt&amp;gt;valgrind &amp;lt;program&amp;gt; &amp;lt;arguements&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Serial code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
&lt;br /&gt;
  // Execution depends on uninitialized value&lt;br /&gt;
  if (array[4] &amp;lt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is negative\n&amp;quot;);&lt;br /&gt;
  else if (array[4] == 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is zero\n&amp;quot;);&lt;br /&gt;
  else if (array[4] &amp;gt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is positive\n&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    printf(&amp;quot;the results are special\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug.  Running this under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reports this&lt;br /&gt;
&lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400511: main (bug.c:7)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x40052C: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400536: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400551: main (bug.c:11)&lt;br /&gt;
&lt;br /&gt;
Note that valgrind only reports uninitialized values usage once they lead to non-determinism (i.e., when the program encounters a branch whose choice depends on the result of an uninitiated value).  This means you the first report you get is frequently not in the calculation done on the uninitialized values but rather the convergence test or print statement at the end of calculations (print statements contains a bunch of branches in order to handling printing of each different digit).&lt;br /&gt;
&lt;br /&gt;
=== Tracking down uninitialized values ===&lt;br /&gt;
&lt;br /&gt;
More typically a program will be composed of multiple routines that all work on the data.  To this end, consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_sequence(double* array, const int array_length) {&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=1; i&amp;lt;array_length+1; ++i)&lt;br /&gt;
    array[i] = i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
  const int array_length = sizeof(array)/sizeof(array[0]);&lt;br /&gt;
&lt;br /&gt;
  double array_sum;&lt;br /&gt;
&lt;br /&gt;
  initialize_sequence(array,array_length);&lt;br /&gt;
  array_sum = sum(array,array_length);&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;the sum of 0..%d is %f\n&amp;quot;, array_length-1, array_sum);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has both indexing and uninitialized value bugs.  Despite this, directly running the code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will mostly likely produce the correct answer on most machines most of the time&lt;br /&gt;
&lt;br /&gt;
 the sum of 0..9 is 45.000000&lt;br /&gt;
&lt;br /&gt;
Running under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reliably gives many warnings of the following form&lt;br /&gt;
&lt;br /&gt;
 ==15930== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==15930==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x400722: main (bug.c:29)&lt;br /&gt;
&lt;br /&gt;
This is a typical numeric code example were the warnings first occur at a print statement because this is the first time the uninitialized value leads to non-determinism (i.e., the program's behaviour is random as it is taking or does not taking a branch based on a result computed from something that was not set by the programmer).&lt;br /&gt;
&lt;br /&gt;
We now know the problem is that something unset went into computing the value of ''array_sum'', so we should trace the ''array_sum'' calculation backwards through the program.  This quickly gets difficult as we then find ourselves also tracing back all variables that went into the ''array_sum'' calculation, and then all variables that went into those variables, and so on.&lt;br /&gt;
&lt;br /&gt;
Fortunately Valgrind provides a ''--track-origins=yes'' flag to ease our search by telling us which variables are the source of the problem.  Re-running with this flag&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
valgrind --track-origins=yes ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gives warning messages augmented to include the source of the uninitialized value that went into the computation of ''array_sum''&lt;br /&gt;
&lt;br /&gt;
 ==17589== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==17589==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x400722: main (bug.c:29)&lt;br /&gt;
 ==17589==  Uninitialised value was created by a stack allocation&lt;br /&gt;
 ==17589==    at 0x400632: sum (bug.c:10)&lt;br /&gt;
&lt;br /&gt;
Now we know the source of the uninitialized value in the ''array_sum'' computation was a local variable in the ''sum'' routine.  Looking into ''sum'' we hopefully figure out without too much difficulty that we forgot to initialize ''array_sum'' to zero.  If our program is producing the correct answer, it is only because we are getting lucky and ''array_sum'' happens to be allocated from memory that is initially zero.&lt;br /&gt;
&lt;br /&gt;
Correcting the ''sum'' routine&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  array_sum = 0.0;&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and re-running under valgrind reveals we are still getting uninitialized values warnings associated with the ''array_sum'' computation.  Now (using the ''--track-origins=yes'') they are of the form&lt;br /&gt;
&lt;br /&gt;
 ==18613== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==18613==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x40072C: main (bug.c:30)&lt;br /&gt;
 ==18613==  Uninitialised value was created by a stack allocation&lt;br /&gt;
 ==18613==    at 0x400690: main (bug.c:21)&lt;br /&gt;
&lt;br /&gt;
Valgrind is now telling us that a local variable inside ''main'' went into the computation of ''array_sum'' despite never being set.  This must be ''array'' itself as ''array_length'' is clearly set to the compiler computed ''sizeof(array)/sizeof(array[0])'' value.&lt;br /&gt;
&lt;br /&gt;
Looking at ''main'' it is clear ''array'' should have been fully initialized by ''initialize_sequence''.  Careful examination of this routine reveals the final error.  The initialization loop was done using Fortran indices (1...''array_length'')  instead of C (0...''array_length-1'').  Correcting this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
void initialize_sequence(double* array, const int array_length) {&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array[i] = i;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
finally produces code the runs under valgrind without any warnings.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' The Valgrind warnings were being generated because the ''array[0]'' value was not being initialized.  The code was also incorrect in that it was initializing ''array[array_length]'' which is one past the end of ''array''.  If you put this later error back into the program and run under Valgrind you will discover it does not produce any warnings.  This shows that even codes that successfully under Valgrind can still contain errors.&lt;br /&gt;
&lt;br /&gt;
=== Call Valgrind from your program ===&lt;br /&gt;
&lt;br /&gt;
In some cases it can be helpful to call Valgrind directly from your program in order to check the status of various bits of memory.  This is easily done by including the ''valgrind/memcheck.h'' header file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;valgrind/memcheck.h&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and then adding calls to the appropriate [http://valgrind.org/docs/manual/mc-manual.html#mc-manual.clientreqs client check routines].  For example, here is a modified ''sum'' routine for the above program that prints a warning if it is called with an ''array'' that is not fully initialized&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  if (VALGRIND_CHECK_MEM_IS_DEFINED(array,sizeof(double)*array_length)) &lt;br /&gt;
    fprintf(stderr,&amp;quot;sum called with an array that is not fully defined...\n&amp;quot;); &lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the ''bug.c'' code under Valgrind with this modification produces the following output&lt;br /&gt;
&lt;br /&gt;
 ==29765== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==29765==    at 0x400745: sum (bug.c:15)&lt;br /&gt;
 ==29765==    by 0x400832: main (bug.c:31)&lt;br /&gt;
 ==29765==  Address 0x7fefff8e8 is on thread 1's stack&lt;br /&gt;
 ==29765== &lt;br /&gt;
 sum called with an array that is not fully defined...&lt;br /&gt;
&lt;br /&gt;
== MPI code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' MPI code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;mpi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc,char *argv[]){&lt;br /&gt;
  int rank, size;&lt;br /&gt;
  int value;&lt;br /&gt;
&lt;br /&gt;
  MPI_Init(&amp;amp;argc, &amp;amp;argv);&lt;br /&gt;
&lt;br /&gt;
  MPI_Comm_rank(MPI_COMM_WORLD, &amp;amp;rank);&lt;br /&gt;
  MPI_Comm_size(MPI_COMM_WORLD, &amp;amp;size);&lt;br /&gt;
&lt;br /&gt;
  if (rank == 0 &amp;amp;&amp;amp; size &amp;gt; 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Irecv(&amp;amp;value, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 0;&lt;br /&gt;
    MPI_Wait (&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  }&lt;br /&gt;
  else if (rank == 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Isend(&amp;amp;value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 1;&lt;br /&gt;
    MPI_Wait(&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  } &lt;br /&gt;
&lt;br /&gt;
  MPI_Finalize();&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug and two race condition bugs around the use of value.&lt;br /&gt;
&lt;br /&gt;
# The first race condition is that rank==0 sets value=0 while at the same time doing a non-blocking receive into value (bug:16).&lt;br /&gt;
# The uninitialized value problem is that rank==1 starts a send of value to rank==0 without ever setting value (bug:22).&lt;br /&gt;
# The second race condition is that rank==1 sets value=1 while at the same time doing a non-blocking send of value (bug:23).&lt;br /&gt;
&lt;br /&gt;
=== Basic Functionality ===&lt;br /&gt;
&lt;br /&gt;
If you run this using the non-debug/valgrind openmpi valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load intel/12.1.3 openmpi/intel/1.6.2&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you are presumably getting a report about the uninitialized value, but it is burried in 55517 other bogus error messages.&lt;br /&gt;
&lt;br /&gt;
This solution to this is to link against the valgrind openmpi debug wrapper library too.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpicc -Wall -g bug.c -L/usr/lib64/valgrind -lmpiwrap-amd64-linux -Xlinker -rpath=/usr/lib64/valgrind -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This now only reports one bogus error (a free on exit) and picks up the sending of the uninitialized value&lt;br /&gt;
&lt;br /&gt;
 ==27638== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27638==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27638==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27638==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27638==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27638==  Address 0x7fefff734 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Advanced Functionality ===&lt;br /&gt;
&lt;br /&gt;
Now, if on top of this, you also bring in the valgrind enabled openmpi debug library, things get really sweet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load intel/12.1.3 openmpi/intel-debug/1.6.2&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
LD_PRELOAD=/usr/lib64/valgrind/libmpiwrap-amd64-linux.so mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You still only get one bogus error (a free on exit) and all the bugs in the code are detected and reported&lt;br /&gt;
&lt;br /&gt;
 ==27774== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27774==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27774==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27774==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27774==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27773== Invalid write of size 4&lt;br /&gt;
 ==27773==    at 0x4026A0: main (bug.c:16)&lt;br /&gt;
 ==27773==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27774== Invalid write of size 4&lt;br /&gt;
 ==27774==    at 0x40271B: main (bug.c:23)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Suppression File ===&lt;br /&gt;
&lt;br /&gt;
There is also a valgrind suppression option &amp;lt;tt&amp;gt;--suppressions=/opt/sharcnet/openmpi/1.6.2/intel-debug/share/openmpi/openmpi-valgrind.supp&amp;lt;/tt&amp;gt;, however we have not observed any cases where this makes a difference yet.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Package website&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.valgrind.org&lt;br /&gt;
&lt;br /&gt;
[[Category:Software packages]]&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11790</id>
		<title>VALGRIND</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11790"/>
				<updated>2015-09-08T16:20:54Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Example of tracking down uninitialized value warnings&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=VALGRIND&lt;br /&gt;
|package_description=Memory debugger&lt;br /&gt;
|package_idnumber=132&lt;br /&gt;
}}&lt;br /&gt;
'''Valgrind''' is a powerful tool for analyzing programs, memory debugging, memory leak detection and profiling.  It is freely available under GNU license.  Version 3.5.0 is available on most SHARCNET systems.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' To avoid spurious warnings it is important to not use too new of a version of GCC or OpenMPI.  We recommend&lt;br /&gt;
&lt;br /&gt;
* gcc/4.8.2&lt;br /&gt;
* openmpi/gcc-debug/1.8.1 modules&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Valgrind is a dynamic binary instrumentation framework that dynamically translates executables to add instrumentation and track all memory and register usages by a program.  The advantages of this approach are that&lt;br /&gt;
&lt;br /&gt;
* it can be directly run on any executable, and&lt;br /&gt;
* dynamic translation allows ultimate instrumentation&lt;br /&gt;
&lt;br /&gt;
while the disadvantages are&lt;br /&gt;
&lt;br /&gt;
* 5-100 x slow down depending on tool,&lt;br /&gt;
* 12-18 x increase in size of translated code, and&lt;br /&gt;
* corner cases may exist between translated code and original.&lt;br /&gt;
&lt;br /&gt;
Several tools have been built upon this framework.  These include&lt;br /&gt;
&lt;br /&gt;
* ''memcheck'' -  memory error detector&lt;br /&gt;
* ''cachegrind'' - cache and branch-prediction profiler&lt;br /&gt;
* ''callgrind'' - call-graph generating cache and branch prediction profiler&lt;br /&gt;
* ''helgrind'' - thread error detector&lt;br /&gt;
* ''DRD'' - thread error detector&lt;br /&gt;
* ''Massif'' - heap profiler&lt;br /&gt;
* ''DHAT'' - dynamic heap analysis tool&lt;br /&gt;
* ''SGCheck'' - experimental stack and global array overrun detector&lt;br /&gt;
* ''BBV'' - experimental basic block vector generation tool&lt;br /&gt;
&lt;br /&gt;
You are welcome to use any or all of these, but we have only used ''memcheck'' and ''cachegrind'' and only support ''memcheck''.&lt;br /&gt;
&lt;br /&gt;
= Usage =&lt;br /&gt;
&lt;br /&gt;
The primary used tool is ''memcheck''.  This is the default tool and the only one we discuss here.  Documentation for other tools can be found on the [http://www.valgrind.org valgrind website].  The memcheck tool detects several common memory errors&lt;br /&gt;
&lt;br /&gt;
* overrunning and underrunning heap blocks,&lt;br /&gt;
* overrunning top of stack,&lt;br /&gt;
* continuing to access released memory,&lt;br /&gt;
* using uninitialized values,&lt;br /&gt;
* incorrectly using memory copying routines,&lt;br /&gt;
* incorrectly paired allocation/release calls,&lt;br /&gt;
* relasing unallocated memory, and&lt;br /&gt;
* not releasing memory.&lt;br /&gt;
&lt;br /&gt;
We recommend running all new code under valgrind on small test cases (small due to the aforementioned ~10x slowdown).  This can save hours and hours of debugging.  Running the program under valgrind can be as simple as compiling with debugging information (adding the &amp;lt;tt&amp;gt;-g&amp;lt;/tt&amp;gt; flag) and running as &amp;lt;tt&amp;gt;valgrind &amp;lt;program&amp;gt; &amp;lt;arguements&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Serial code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
&lt;br /&gt;
  // Execution depends on uninitialized value&lt;br /&gt;
  if (array[4] &amp;lt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is negative\n&amp;quot;);&lt;br /&gt;
  else if (array[4] == 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is zero\n&amp;quot;);&lt;br /&gt;
  else if (array[4] &amp;gt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is positive\n&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    printf(&amp;quot;the results are special\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug.  Running this under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reports this&lt;br /&gt;
&lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400511: main (bug.c:7)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x40052C: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400536: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400551: main (bug.c:11)&lt;br /&gt;
&lt;br /&gt;
Note that valgrind only reports uninitialized values usage once they lead to non-determinism (i.e., when the program encounters a branch whose choice depends on the result of an uninitiated value).  This means you the first report you get is frequently not in the calculation done on the uninitialized values but rather the convergence test or print statement at the end of calculations (print statements contains a bunch of branches in order to handling printing of each different digit).&lt;br /&gt;
&lt;br /&gt;
=== Tracking down uninitialized values ===&lt;br /&gt;
&lt;br /&gt;
More typically a program will be composed of multiple routines that all work on the data.  To this end, consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_sequence(double* array, const int array_length) {&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=1; i&amp;lt;array_length+1; ++i)&lt;br /&gt;
    array[i] = i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
  const int array_length = sizeof(array)/sizeof(array[0]);&lt;br /&gt;
&lt;br /&gt;
  double array_sum;&lt;br /&gt;
&lt;br /&gt;
  initialize_sequence(array,array_length);&lt;br /&gt;
  array_sum = sum(array,array_length);&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;the sum of 0..%d is %f\n&amp;quot;, array_length-1, array_sum);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has both indexing and uninitialized value bugs.  Despite this, directly running the code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will mostly likely produce the correct answer on most machines most of the time&lt;br /&gt;
&lt;br /&gt;
 the sum of 0..9 is 45.000000&lt;br /&gt;
&lt;br /&gt;
Running under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reliably gives many warnings of the following form&lt;br /&gt;
&lt;br /&gt;
 ==15930== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==15930==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x400722: main (bug.c:29)&lt;br /&gt;
&lt;br /&gt;
This is a typical numeric code example were the warnings first occur at a print statement because this is the first time the uninitialized value leads to non-determinism (i.e., the program's behaviour is random as it is taking or does not taking a branch based on a result computed from something that was not set by the programmer).&lt;br /&gt;
&lt;br /&gt;
We now know the problem is that something unset went into computing the value of ''array_sum'', so we should trace the ''array_sum'' calculation backwards through the program.  This quickly gets difficult as we then find ourselves also tracing back all variables that went into the ''array_sum'' calculation, and then all variables that went into those variables, and so on.&lt;br /&gt;
&lt;br /&gt;
Fortunately Valgrind provides a ''--track-origins=yes'' flag to ease our search by telling us which variables are the source of the problem.  Re-running with this flag&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
valgrind --track-origins=yes ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gives warning messages augmented to include the source of the uninitialized value that went into the computation of ''array_sum''&lt;br /&gt;
&lt;br /&gt;
 ==17589== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==17589==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x400722: main (bug.c:29)&lt;br /&gt;
 ==17589==  Uninitialised value was created by a stack allocation&lt;br /&gt;
 ==17589==    at 0x400632: sum (bug.c:10)&lt;br /&gt;
&lt;br /&gt;
Now we know the source of the uninitialized value in the ''array_sum'' computation was a local variable in the ''sum'' routine.  Looking into ''sum'' we hopefully figure out without too much difficulty that we forgot to initialize ''array_sum'' to zero.  If our program is producing the correct answer, it is only because we are getting lucky and ''array_sum'' happens to be allocated from memory that is initially zero.&lt;br /&gt;
&lt;br /&gt;
Correcting the ''sum'' routine&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  array_sum = 0.0;&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and re-running under valgrind reveals we are still getting uninitialized values warnings associated with the ''array_sum'' computation.  Now (using the ''--track-origins=yes'') they are of the form&lt;br /&gt;
&lt;br /&gt;
 ==18613== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==18613==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x40072C: main (bug.c:30)&lt;br /&gt;
 ==18613==  Uninitialised value was created by a stack allocation&lt;br /&gt;
 ==18613==    at 0x400690: main (bug.c:21)&lt;br /&gt;
&lt;br /&gt;
Valgrind is now telling us that a local variable inside ''main'' went into the computation of ''array_sum'' despite never being set.  This must be ''array'' itself as ''array_length'' is clearly set to the compiler computed ''sizeof(array)/sizeof(array[0])'' value.&lt;br /&gt;
&lt;br /&gt;
Looking at ''main'' it is clear ''array'' should have been fully initialized by ''initialize_sequence''.  Careful examination of this routine reveals the final error.  The initialization loop was done using Fortran indices (1...''array_length'')  instead of C (0...''array_length-1'').  Correcting this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
void initialize_sequence(double* array, const int array_length) {&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array[i] = i;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
finally produces code the runs under valgrind without any warnings.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' The Valgrind warnings were being generated because the ''array[0]'' value was not being initialized.  The code was also incorrect in that it was initializing ''array[array_length]'' which is one past the end of ''array''.  If you put this later error back into the program and run under Valgrind you will discover it does not produce any warnings.  This shows that even codes that successfully under Valgrind can still contain errors.&lt;br /&gt;
&lt;br /&gt;
== MPI code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' MPI code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;mpi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc,char *argv[]){&lt;br /&gt;
  int rank, size;&lt;br /&gt;
  int value;&lt;br /&gt;
&lt;br /&gt;
  MPI_Init(&amp;amp;argc, &amp;amp;argv);&lt;br /&gt;
&lt;br /&gt;
  MPI_Comm_rank(MPI_COMM_WORLD, &amp;amp;rank);&lt;br /&gt;
  MPI_Comm_size(MPI_COMM_WORLD, &amp;amp;size);&lt;br /&gt;
&lt;br /&gt;
  if (rank == 0 &amp;amp;&amp;amp; size &amp;gt; 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Irecv(&amp;amp;value, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 0;&lt;br /&gt;
    MPI_Wait (&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  }&lt;br /&gt;
  else if (rank == 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Isend(&amp;amp;value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 1;&lt;br /&gt;
    MPI_Wait(&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  } &lt;br /&gt;
&lt;br /&gt;
  MPI_Finalize();&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug and two race condition bugs around the use of value.&lt;br /&gt;
&lt;br /&gt;
# The first race condition is that rank==0 sets value=0 while at the same time doing a non-blocking receive into value (bug:16).&lt;br /&gt;
# The uninitialized value problem is that rank==1 starts a send of value to rank==0 without ever setting value (bug:22).&lt;br /&gt;
# The second race condition is that rank==1 sets value=1 while at the same time doing a non-blocking send of value (bug:23).&lt;br /&gt;
&lt;br /&gt;
=== Basic Functionality ===&lt;br /&gt;
&lt;br /&gt;
If you run this using the non-debug/valgrind openmpi valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load intel/12.1.3 openmpi/intel/1.6.2&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you are presumably getting a report about the uninitialized value, but it is burried in 55517 other bogus error messages.&lt;br /&gt;
&lt;br /&gt;
This solution to this is to link against the valgrind openmpi debug wrapper library too.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpicc -Wall -g bug.c -L/usr/lib64/valgrind -lmpiwrap-amd64-linux -Xlinker -rpath=/usr/lib64/valgrind -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This now only reports one bogus error (a free on exit) and picks up the sending of the uninitialized value&lt;br /&gt;
&lt;br /&gt;
 ==27638== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27638==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27638==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27638==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27638==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27638==  Address 0x7fefff734 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Advanced Functionality ===&lt;br /&gt;
&lt;br /&gt;
Now, if on top of this, you also bring in the valgrind enabled openmpi debug library, things get really sweet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load intel/12.1.3 openmpi/intel-debug/1.6.2&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
LD_PRELOAD=/usr/lib64/valgrind/libmpiwrap-amd64-linux.so mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You still only get one bogus error (a free on exit) and all the bugs in the code are detected and reported&lt;br /&gt;
&lt;br /&gt;
 ==27774== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27774==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27774==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27774==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27774==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27773== Invalid write of size 4&lt;br /&gt;
 ==27773==    at 0x4026A0: main (bug.c:16)&lt;br /&gt;
 ==27773==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27774== Invalid write of size 4&lt;br /&gt;
 ==27774==    at 0x40271B: main (bug.c:23)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Suppression File ===&lt;br /&gt;
&lt;br /&gt;
There is also a valgrind suppression option &amp;lt;tt&amp;gt;--suppressions=/opt/sharcnet/openmpi/1.6.2/intel-debug/share/openmpi/openmpi-valgrind.supp&amp;lt;/tt&amp;gt;, however we have not observed any cases where this makes a difference yet.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Package website&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.valgrind.org&lt;br /&gt;
&lt;br /&gt;
[[Category:Software packages]]&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11789</id>
		<title>VALGRIND</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11789"/>
				<updated>2015-09-08T16:11:31Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Add directions on tracking down uninitialized values&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=VALGRIND&lt;br /&gt;
|package_description=Memory debugger&lt;br /&gt;
|package_idnumber=132&lt;br /&gt;
}}&lt;br /&gt;
'''Valgrind''' is a powerful tool for analyzing programs, memory debugging, memory leak detection and profiling.  It is freely available under GNU license.  Version 3.5.0 is available on most SHARCNET systems.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' To avoid spurious warnings it is important to not use too new of a version of GCC or OpenMPI.  We recommend&lt;br /&gt;
&lt;br /&gt;
* gcc/4.8.2&lt;br /&gt;
* openmpi/gcc-debug/1.8.1 modules&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Valgrind is a dynamic binary instrumentation framework that dynamically translates executables to add instrumentation and track all memory and register usages by a program.  The advantages of this approach are that&lt;br /&gt;
&lt;br /&gt;
* it can be directly run on any executable, and&lt;br /&gt;
* dynamic translation allows ultimate instrumentation&lt;br /&gt;
&lt;br /&gt;
while the disadvantages are&lt;br /&gt;
&lt;br /&gt;
* 5-100 x slow down depending on tool,&lt;br /&gt;
* 12-18 x increase in size of translated code, and&lt;br /&gt;
* corner cases may exist between translated code and original.&lt;br /&gt;
&lt;br /&gt;
Several tools have been built upon this framework.  These include&lt;br /&gt;
&lt;br /&gt;
* ''memcheck'' -  memory error detector&lt;br /&gt;
* ''cachegrind'' - cache and branch-prediction profiler&lt;br /&gt;
* ''callgrind'' - call-graph generating cache and branch prediction profiler&lt;br /&gt;
* ''helgrind'' - thread error detector&lt;br /&gt;
* ''DRD'' - thread error detector&lt;br /&gt;
* ''Massif'' - heap profiler&lt;br /&gt;
* ''DHAT'' - dynamic heap analysis tool&lt;br /&gt;
* ''SGCheck'' - experimental stack and global array overrun detector&lt;br /&gt;
* ''BBV'' - experimental basic block vector generation tool&lt;br /&gt;
&lt;br /&gt;
You are welcome to use any or all of these, but we have only used ''memcheck'' and ''cachegrind'' and only support ''memcheck''.&lt;br /&gt;
&lt;br /&gt;
= Usage =&lt;br /&gt;
&lt;br /&gt;
The primary used tool is ''memcheck''.  This is the default tool and the only one we discuss here.  Documentation for other tools can be found on the [http://www.valgrind.org valgrind website].  The memcheck tool detects several common memory errors&lt;br /&gt;
&lt;br /&gt;
* overrunning and underrunning heap blocks,&lt;br /&gt;
* overrunning top of stack,&lt;br /&gt;
* continuing to access released memory,&lt;br /&gt;
* using uninitialized values,&lt;br /&gt;
* incorrectly using memory copying routines,&lt;br /&gt;
* incorrectly paired allocation/release calls,&lt;br /&gt;
* relasing unallocated memory, and&lt;br /&gt;
* not releasing memory.&lt;br /&gt;
&lt;br /&gt;
We recommend running all new code under valgrind on small test cases (small due to the aforementioned ~10x slowdown).  This can save hours and hours of debugging.  Running the program under valgrind can be as simple as compiling with debugging information (adding the &amp;lt;tt&amp;gt;-g&amp;lt;/tt&amp;gt; flag) and running as &amp;lt;tt&amp;gt;valgrind &amp;lt;program&amp;gt; &amp;lt;arguements&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Serial code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
&lt;br /&gt;
  // Execution depends on uninitialized value&lt;br /&gt;
  if (array[4] &amp;lt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is negative\n&amp;quot;);&lt;br /&gt;
  else if (array[4] == 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is zero\n&amp;quot;);&lt;br /&gt;
  else if (array[4] &amp;gt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is positive\n&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    printf(&amp;quot;the results are special\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug.  Running this under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reports this&lt;br /&gt;
&lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400511: main (bug.c:7)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x40052C: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400536: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400551: main (bug.c:11)&lt;br /&gt;
&lt;br /&gt;
Note that valgrind only reports uninitialized values usage once they lead to non-determinism (i.e., when the program encounters a branch whose choice depends on the result of an uninitiated value).  This means you the first report you get is frequently not in the calculation done on the uninitialized values but rather the convergence test or print statement at the end of calculations (print statements contains a bunch of branches in order to handling printing of each different digit).&lt;br /&gt;
&lt;br /&gt;
=== Tracking down uninitialized values ===&lt;br /&gt;
&lt;br /&gt;
More typically a program will be composed of multiple routines that all work on the data.  To this end, consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_sequence(double* array, const int array_length) {&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=1; i&amp;lt;array_length+1; ++i)&lt;br /&gt;
    array[i] = i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
  const int array_length = sizeof(array)/sizeof(array[0]);&lt;br /&gt;
&lt;br /&gt;
  double array_sum;&lt;br /&gt;
&lt;br /&gt;
  initialize_sequence(array,array_length);&lt;br /&gt;
  array_sum = sum(array,array_length);&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;the sum of 0..%d is %f\n&amp;quot;, array_length-1, array_sum);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has both indexing and uninitialized value bugs.  Despite this, directly running the code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will mostly likely produce the correct answer on most machines most of the time&lt;br /&gt;
&lt;br /&gt;
 the sum of 0..9 is 45.000000&lt;br /&gt;
&lt;br /&gt;
Running under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
however, reliably gives many warnings of the following form&lt;br /&gt;
&lt;br /&gt;
 ==15930== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==15930==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==15930==    by 0x400722: main (bug.c:29)&lt;br /&gt;
&lt;br /&gt;
This is a typical numeric code example were the warnings first occur at a print statement because this is the first time the uninitialized value leads to non-determinism (i.e., the program's behaviour is altered as it takes or does not take a branch based on a result computed from something that was not set by the programmer).&lt;br /&gt;
&lt;br /&gt;
We now know the problem is that something unset went into computing the value of ''array_sum''.  We can then trace each of the ''array_sum'' calculation backwards.  This quickly gets difficult though as we then find ourselves also tracing back all variables that went into the ''array_sum'' calculation, and then all variables that went into those variables and so on.&lt;br /&gt;
&lt;br /&gt;
Fortunately Valgrind provides a ''--track-origins=yes'' flag to ease our search by telling us which ones we can ignore.  Re-running with this flag&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
valgrind --track-origins=yes ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
our warnings messages are augmented to include information on the source of the uninitialized value that went into the computation of ''array_sum''&lt;br /&gt;
&lt;br /&gt;
 ==17589== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==17589==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==17589==    by 0x400722: main (bug.c:29)&lt;br /&gt;
 ==17589==  Uninitialised value was created by a stack allocation&lt;br /&gt;
 ==17589==    at 0x400632: sum (bug.c:10)&lt;br /&gt;
&lt;br /&gt;
Now we know the source of our uninitialized value in the ''array_sum'' computation is a local variable in the ''sum'' routine.  Looking into ''sum'' we hopefully figure out without too much difficulty that we forgot to initialize ''array_sum'' to zero.  If our program is producing the correct answer, it is only because we are getting lucky and ''array_sum'' happens to be allocated from memory that is initially zero.&lt;br /&gt;
&lt;br /&gt;
Correcting the ''sum'' routine&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
double sum(const double* array, const int array_length) {&lt;br /&gt;
  double array_sum;&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  array_sum = 0.0;&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array_sum += array[i];&lt;br /&gt;
&lt;br /&gt;
  return array_sum;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and re-running under valgrind reveals we are still getting uninitialized values warnings associated with the ''array_sum'' computation.  Now (using the ''--track-origins=yes'') they are of the form&lt;br /&gt;
&lt;br /&gt;
 ==18613== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==18613==    at 0x5312CF0: __printf_fp (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x530E89F: vfprintf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x5318189: printf (in /lib64/libc-2.12.so)&lt;br /&gt;
 ==18613==    by 0x40072C: main (bug.c:30)&lt;br /&gt;
 ==18613==  Uninitialised value was created by a stack allocation&lt;br /&gt;
 ==18613==    at 0x400690: main (bug.c:21)&lt;br /&gt;
&lt;br /&gt;
Valgrind is telling us that a local variable inside the ''main'' went into the computation of ''array_sum'' despite never being set.  This means it must be ''array'' itself or ''array_length''.  It cannot be ''array_length'' as the former is clearly set to the compiler computed ''sizeof(array)/sizeof(array[0])'' so it must be ''array'' itself.&lt;br /&gt;
&lt;br /&gt;
It is clear the intent of the code is that ''array'' is initialized by the ''initialize_sequence'' routine.  Careful examination of this routine reveals the final error.  The initialization loop was done using Fortran indices (1...''array_length'')  instead of C (0...''array_length-1'').  Correcting this routine&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
void initialize_sequence(double* array, const int array_length) {&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;array_length; ++i)&lt;br /&gt;
    array[i] = i;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
finally produces code the runs under valgrind without any warnings.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' The Valgrind warnings were being generated because the ''array[0]'' value was not being initialized.  The code was also incorrect in that it was initializing ''array[array_length]'' which is one past the end of ''array''.  If you put this later error back into the program and run under Valgrind you will discover it does not produce any warnings.  This shows that even codes that successfully under Valgrind can still contain errors.&lt;br /&gt;
&lt;br /&gt;
== MPI code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' MPI code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;mpi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc,char *argv[]){&lt;br /&gt;
  int rank, size;&lt;br /&gt;
  int value;&lt;br /&gt;
&lt;br /&gt;
  MPI_Init(&amp;amp;argc, &amp;amp;argv);&lt;br /&gt;
&lt;br /&gt;
  MPI_Comm_rank(MPI_COMM_WORLD, &amp;amp;rank);&lt;br /&gt;
  MPI_Comm_size(MPI_COMM_WORLD, &amp;amp;size);&lt;br /&gt;
&lt;br /&gt;
  if (rank == 0 &amp;amp;&amp;amp; size &amp;gt; 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Irecv(&amp;amp;value, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 0;&lt;br /&gt;
    MPI_Wait (&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  }&lt;br /&gt;
  else if (rank == 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Isend(&amp;amp;value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 1;&lt;br /&gt;
    MPI_Wait(&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  } &lt;br /&gt;
&lt;br /&gt;
  MPI_Finalize();&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug and two race condition bugs around the use of value.&lt;br /&gt;
&lt;br /&gt;
# The first race condition is that rank==0 sets value=0 while at the same time doing a non-blocking receive into value (bug:16).&lt;br /&gt;
# The uninitialized value problem is that rank==1 starts a send of value to rank==0 without ever setting value (bug:22).&lt;br /&gt;
# The second race condition is that rank==1 sets value=1 while at the same time doing a non-blocking send of value (bug:23).&lt;br /&gt;
&lt;br /&gt;
=== Basic Functionality ===&lt;br /&gt;
&lt;br /&gt;
If you run this using the non-debug/valgrind openmpi valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load intel/12.1.3 openmpi/intel/1.6.2&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you are presumably getting a report about the uninitialized value, but it is burried in 55517 other bogus error messages.&lt;br /&gt;
&lt;br /&gt;
This solution to this is to link against the valgrind openmpi debug wrapper library too.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpicc -Wall -g bug.c -L/usr/lib64/valgrind -lmpiwrap-amd64-linux -Xlinker -rpath=/usr/lib64/valgrind -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This now only reports one bogus error (a free on exit) and picks up the sending of the uninitialized value&lt;br /&gt;
&lt;br /&gt;
 ==27638== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27638==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27638==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27638==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27638==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27638==  Address 0x7fefff734 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Advanced Functionality ===&lt;br /&gt;
&lt;br /&gt;
Now, if on top of this, you also bring in the valgrind enabled openmpi debug library, things get really sweet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load intel/12.1.3 openmpi/intel-debug/1.6.2&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
LD_PRELOAD=/usr/lib64/valgrind/libmpiwrap-amd64-linux.so mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You still only get one bogus error (a free on exit) and all the bugs in the code are detected and reported&lt;br /&gt;
&lt;br /&gt;
 ==27774== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27774==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27774==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27774==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27774==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27773== Invalid write of size 4&lt;br /&gt;
 ==27773==    at 0x4026A0: main (bug.c:16)&lt;br /&gt;
 ==27773==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27774== Invalid write of size 4&lt;br /&gt;
 ==27774==    at 0x40271B: main (bug.c:23)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Suppression File ===&lt;br /&gt;
&lt;br /&gt;
There is also a valgrind suppression option &amp;lt;tt&amp;gt;--suppressions=/opt/sharcnet/openmpi/1.6.2/intel-debug/share/openmpi/openmpi-valgrind.supp&amp;lt;/tt&amp;gt;, however we have not observed any cases where this makes a difference yet.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Package website&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.valgrind.org&lt;br /&gt;
&lt;br /&gt;
[[Category:Software packages]]&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11787</id>
		<title>VALGRIND</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11787"/>
				<updated>2015-09-08T14:34:22Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Reformat version recommendations to make the more prominent&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=VALGRIND&lt;br /&gt;
|package_description=Memory debugger&lt;br /&gt;
|package_idnumber=132&lt;br /&gt;
}}&lt;br /&gt;
'''Valgrind''' is a powerful tool for analyzing programs, memory debugging, memory leak detection and profiling.  It is freely available under GNU license.  Version 3.5.0 is available on most SHARCNET systems.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''' To avoid spurious warnings it is important to not use too new of a version of GCC or OpenMPI.  We recommend&lt;br /&gt;
&lt;br /&gt;
* gcc/4.8.2&lt;br /&gt;
* openmpi/gcc-debug/1.8.1 modules&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Valgrind is a dynamic binary instrumentation framework that dynamically translates executables to add instrumentation and track all memory and register usages by a program.  The advantages of this approach are that&lt;br /&gt;
&lt;br /&gt;
* it can be directly run on any executable, and&lt;br /&gt;
* dynamic translation allows ultimate instrumentation&lt;br /&gt;
&lt;br /&gt;
while the disadvantages are&lt;br /&gt;
&lt;br /&gt;
* 5-100 x slow down depending on tool,&lt;br /&gt;
* 12-18 x increase in size of translated code, and&lt;br /&gt;
* corner cases may exist between translated code and original.&lt;br /&gt;
&lt;br /&gt;
Several tools have been built upon this framework.  These include&lt;br /&gt;
&lt;br /&gt;
* ''memcheck'' -  memory error detector&lt;br /&gt;
* ''cachegrind'' - cache and branch-prediction profiler&lt;br /&gt;
* ''callgrind'' - call-graph generating cache and branch prediction profiler&lt;br /&gt;
* ''helgrind'' - thread error detector&lt;br /&gt;
* ''DRD'' - thread error detector&lt;br /&gt;
* ''Massif'' - heap profiler&lt;br /&gt;
* ''DHAT'' - dynamic heap analysis tool&lt;br /&gt;
* ''SGCheck'' - experimental stack and global array overrun detector&lt;br /&gt;
* ''BBV'' - experimental basic block vector generation tool&lt;br /&gt;
&lt;br /&gt;
You are welcome to use any or all of these, but we have only used ''memcheck'' and ''cachegrind'' and only support ''memcheck''.&lt;br /&gt;
&lt;br /&gt;
= Usage =&lt;br /&gt;
&lt;br /&gt;
The primary used tool is ''memcheck''.  This is the default tool and the only one we discuss here.  Documentation for other tools can be found on the [http://www.valgrind.org valgrind website].  The memcheck tool detects several common memory errors&lt;br /&gt;
&lt;br /&gt;
* overrunning and underrunning heap blocks,&lt;br /&gt;
* overrunning top of stack,&lt;br /&gt;
* continuing to access released memory,&lt;br /&gt;
* using uninitialized values,&lt;br /&gt;
* incorrectly using memory copying routines,&lt;br /&gt;
* incorrectly paired allocation/release calls,&lt;br /&gt;
* relasing unallocated memory, and&lt;br /&gt;
* not releasing memory.&lt;br /&gt;
&lt;br /&gt;
We recommend running all new code under valgrind on small test cases (small due to the aforementioned ~10x slowdown).  This can save hours and hours of debugging.  Running the program under valgrind can be as simple as compiling with debugging information (adding the &amp;lt;tt&amp;gt;-g&amp;lt;/tt&amp;gt; flag) and running as &amp;lt;tt&amp;gt;valgrind &amp;lt;program&amp;gt; &amp;lt;arguements&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Serial code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
&lt;br /&gt;
  // Execution depends on uninitialized value&lt;br /&gt;
  if (array[4] &amp;lt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is negative\n&amp;quot;);&lt;br /&gt;
  else if (array[4] == 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is zero\n&amp;quot;);&lt;br /&gt;
  else if (array[4] &amp;gt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is positive\n&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    printf(&amp;quot;the results are special\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug.  Running this under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reports this&lt;br /&gt;
&lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400511: main (bug.c:7)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x40052C: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400536: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400551: main (bug.c:11)&lt;br /&gt;
&lt;br /&gt;
Note that valgrind only reports uninitialized values usage once they lead to non-determinism (i.e., when the program encounters a branch whose choice depends on the result of an uninitiated value).  This means you the first report you get is frequently not in the calculation done on the uninitialized values but rather the convergence test or print statement at the end of calculations (print statements contains a bunch of branches in order to handling printing of each different digit).&lt;br /&gt;
&lt;br /&gt;
== MPI code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' MPI code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;mpi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc,char *argv[]){&lt;br /&gt;
  int rank, size;&lt;br /&gt;
  int value;&lt;br /&gt;
&lt;br /&gt;
  MPI_Init(&amp;amp;argc, &amp;amp;argv);&lt;br /&gt;
&lt;br /&gt;
  MPI_Comm_rank(MPI_COMM_WORLD, &amp;amp;rank);&lt;br /&gt;
  MPI_Comm_size(MPI_COMM_WORLD, &amp;amp;size);&lt;br /&gt;
&lt;br /&gt;
  if (rank == 0 &amp;amp;&amp;amp; size &amp;gt; 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Irecv(&amp;amp;value, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 0;&lt;br /&gt;
    MPI_Wait (&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  }&lt;br /&gt;
  else if (rank == 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Isend(&amp;amp;value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 1;&lt;br /&gt;
    MPI_Wait(&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  } &lt;br /&gt;
&lt;br /&gt;
  MPI_Finalize();&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug and two race condition bugs around the use of value.&lt;br /&gt;
&lt;br /&gt;
# The first race condition is that rank==0 sets value=0 while at the same time doing a non-blocking receive into value (bug:16).&lt;br /&gt;
# The uninitialized value problem is that rank==1 starts a send of value to rank==0 without ever setting value (bug:22).&lt;br /&gt;
# The second race condition is that rank==1 sets value=1 while at the same time doing a non-blocking send of value (bug:23).&lt;br /&gt;
&lt;br /&gt;
=== Basic Functionality ===&lt;br /&gt;
&lt;br /&gt;
If you run this using the non-debug/valgrind openmpi valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load intel/12.1.3 openmpi/intel/1.6.2&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you are presumably getting a report about the uninitialized value, but it is burried in 55517 other bogus error messages.&lt;br /&gt;
&lt;br /&gt;
This solution to this is to link against the valgrind openmpi debug wrapper library too.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpicc -Wall -g bug.c -L/usr/lib64/valgrind -lmpiwrap-amd64-linux -Xlinker -rpath=/usr/lib64/valgrind -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This now only reports one bogus error (a free on exit) and picks up the sending of the uninitialized value&lt;br /&gt;
&lt;br /&gt;
 ==27638== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27638==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27638==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27638==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27638==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27638==  Address 0x7fefff734 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Advanced Functionality ===&lt;br /&gt;
&lt;br /&gt;
Now, if on top of this, you also bring in the valgrind enabled openmpi debug library, things get really sweet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load intel/12.1.3 openmpi/intel-debug/1.6.2&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
LD_PRELOAD=/usr/lib64/valgrind/libmpiwrap-amd64-linux.so mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You still only get one bogus error (a free on exit) and all the bugs in the code are detected and reported&lt;br /&gt;
&lt;br /&gt;
 ==27774== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27774==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27774==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27774==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27774==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27773== Invalid write of size 4&lt;br /&gt;
 ==27773==    at 0x4026A0: main (bug.c:16)&lt;br /&gt;
 ==27773==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27774== Invalid write of size 4&lt;br /&gt;
 ==27774==    at 0x40271B: main (bug.c:23)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Suppression File ===&lt;br /&gt;
&lt;br /&gt;
There is also a valgrind suppression option &amp;lt;tt&amp;gt;--suppressions=/opt/sharcnet/openmpi/1.6.2/intel-debug/share/openmpi/openmpi-valgrind.supp&amp;lt;/tt&amp;gt;, however we have not observed any cases where this makes a difference yet.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Package website&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.valgrind.org&lt;br /&gt;
&lt;br /&gt;
[[Category:Software packages]]&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11786</id>
		<title>VALGRIND</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=11786"/>
				<updated>2015-09-08T14:32:50Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Make a note of GCC and OpenMPI version recommendation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=VALGRIND&lt;br /&gt;
|package_description=Memory debugger&lt;br /&gt;
|package_idnumber=132&lt;br /&gt;
}}&lt;br /&gt;
'''Valgrind''' is a powerful tool for analyzing programs, memory debugging, memory leak detection and profiling.  It is freely available under GNU license.&lt;br /&gt;
&lt;br /&gt;
Valgrind version 3.5.0 is available on most SHARCNET systems.  To avoid spurious warnings it is important to not use too new of a version of GCC or OpenMPI.  We recommend&lt;br /&gt;
&lt;br /&gt;
* gcc/4.8.2&lt;br /&gt;
* openmpi/gcc-debug/1.8.1 modules&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Valgrind is a dynamic binary instrumentation framework that dynamically translates executables to add instrumentation and track all memory and register usages by a program.  The advantages of this approach are that&lt;br /&gt;
&lt;br /&gt;
* it can be directly run on any executable, and&lt;br /&gt;
* dynamic translation allows ultimate instrumentation&lt;br /&gt;
&lt;br /&gt;
while the disadvantages are&lt;br /&gt;
&lt;br /&gt;
* 5-100 x slow down depending on tool,&lt;br /&gt;
* 12-18 x increase in size of translated code, and&lt;br /&gt;
* corner cases may exist between translated code and original.&lt;br /&gt;
&lt;br /&gt;
Several tools have been built upon this framework.  These include&lt;br /&gt;
&lt;br /&gt;
* ''memcheck'' -  memory error detector&lt;br /&gt;
* ''cachegrind'' - cache and branch-prediction profiler&lt;br /&gt;
* ''callgrind'' - call-graph generating cache and branch prediction profiler&lt;br /&gt;
* ''helgrind'' - thread error detector&lt;br /&gt;
* ''DRD'' - thread error detector&lt;br /&gt;
* ''Massif'' - heap profiler&lt;br /&gt;
* ''DHAT'' - dynamic heap analysis tool&lt;br /&gt;
* ''SGCheck'' - experimental stack and global array overrun detector&lt;br /&gt;
* ''BBV'' - experimental basic block vector generation tool&lt;br /&gt;
&lt;br /&gt;
You are welcome to use any or all of these, but we have only used ''memcheck'' and ''cachegrind'' and only support ''memcheck''.&lt;br /&gt;
&lt;br /&gt;
= Usage =&lt;br /&gt;
&lt;br /&gt;
The primary used tool is ''memcheck''.  This is the default tool and the only one we discuss here.  Documentation for other tools can be found on the [http://www.valgrind.org valgrind website].  The memcheck tool detects several common memory errors&lt;br /&gt;
&lt;br /&gt;
* overrunning and underrunning heap blocks,&lt;br /&gt;
* overrunning top of stack,&lt;br /&gt;
* continuing to access released memory,&lt;br /&gt;
* using uninitialized values,&lt;br /&gt;
* incorrectly using memory copying routines,&lt;br /&gt;
* incorrectly paired allocation/release calls,&lt;br /&gt;
* relasing unallocated memory, and&lt;br /&gt;
* not releasing memory.&lt;br /&gt;
&lt;br /&gt;
We recommend running all new code under valgrind on small test cases (small due to the aforementioned ~10x slowdown).  This can save hours and hours of debugging.  Running the program under valgrind can be as simple as compiling with debugging information (adding the &amp;lt;tt&amp;gt;-g&amp;lt;/tt&amp;gt; flag) and running as &amp;lt;tt&amp;gt;valgrind &amp;lt;program&amp;gt; &amp;lt;arguements&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Serial code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
&lt;br /&gt;
  // Execution depends on uninitialized value&lt;br /&gt;
  if (array[4] &amp;lt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is negative\n&amp;quot;);&lt;br /&gt;
  else if (array[4] == 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is zero\n&amp;quot;);&lt;br /&gt;
  else if (array[4] &amp;gt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is positive\n&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    printf(&amp;quot;the results are special\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug.  Running this under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reports this&lt;br /&gt;
&lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400511: main (bug.c:7)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x40052C: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400536: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400551: main (bug.c:11)&lt;br /&gt;
&lt;br /&gt;
Note that valgrind only reports uninitialized values usage once they lead to non-determinism (i.e., when the program encounters a branch whose choice depends on the result of an uninitiated value).  This means you the first report you get is frequently not in the calculation done on the uninitialized values but rather the convergence test or print statement at the end of calculations (print statements contains a bunch of branches in order to handling printing of each different digit).&lt;br /&gt;
&lt;br /&gt;
== MPI code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' MPI code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;mpi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc,char *argv[]){&lt;br /&gt;
  int rank, size;&lt;br /&gt;
  int value;&lt;br /&gt;
&lt;br /&gt;
  MPI_Init(&amp;amp;argc, &amp;amp;argv);&lt;br /&gt;
&lt;br /&gt;
  MPI_Comm_rank(MPI_COMM_WORLD, &amp;amp;rank);&lt;br /&gt;
  MPI_Comm_size(MPI_COMM_WORLD, &amp;amp;size);&lt;br /&gt;
&lt;br /&gt;
  if (rank == 0 &amp;amp;&amp;amp; size &amp;gt; 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Irecv(&amp;amp;value, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 0;&lt;br /&gt;
    MPI_Wait (&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  }&lt;br /&gt;
  else if (rank == 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Isend(&amp;amp;value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 1;&lt;br /&gt;
    MPI_Wait(&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  } &lt;br /&gt;
&lt;br /&gt;
  MPI_Finalize();&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug and two race condition bugs around the use of value.&lt;br /&gt;
&lt;br /&gt;
# The first race condition is that rank==0 sets value=0 while at the same time doing a non-blocking receive into value (bug:16).&lt;br /&gt;
# The uninitialized value problem is that rank==1 starts a send of value to rank==0 without ever setting value (bug:22).&lt;br /&gt;
# The second race condition is that rank==1 sets value=1 while at the same time doing a non-blocking send of value (bug:23).&lt;br /&gt;
&lt;br /&gt;
=== Basic Functionality ===&lt;br /&gt;
&lt;br /&gt;
If you run this using the non-debug/valgrind openmpi valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load intel/12.1.3 openmpi/intel/1.6.2&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you are presumably getting a report about the uninitialized value, but it is burried in 55517 other bogus error messages.&lt;br /&gt;
&lt;br /&gt;
This solution to this is to link against the valgrind openmpi debug wrapper library too.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpicc -Wall -g bug.c -L/usr/lib64/valgrind -lmpiwrap-amd64-linux -Xlinker -rpath=/usr/lib64/valgrind -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This now only reports one bogus error (a free on exit) and picks up the sending of the uninitialized value&lt;br /&gt;
&lt;br /&gt;
 ==27638== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27638==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27638==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27638==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27638==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27638==  Address 0x7fefff734 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Advanced Functionality ===&lt;br /&gt;
&lt;br /&gt;
Now, if on top of this, you also bring in the valgrind enabled openmpi debug library, things get really sweet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load intel/12.1.3 openmpi/intel-debug/1.6.2&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
LD_PRELOAD=/usr/lib64/valgrind/libmpiwrap-amd64-linux.so mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You still only get one bogus error (a free on exit) and all the bugs in the code are detected and reported&lt;br /&gt;
&lt;br /&gt;
 ==27774== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27774==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27774==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27774==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27774==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27773== Invalid write of size 4&lt;br /&gt;
 ==27773==    at 0x4026A0: main (bug.c:16)&lt;br /&gt;
 ==27773==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27774== Invalid write of size 4&lt;br /&gt;
 ==27774==    at 0x40271B: main (bug.c:23)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Suppression File ===&lt;br /&gt;
&lt;br /&gt;
There is also a valgrind suppression option &amp;lt;tt&amp;gt;--suppressions=/opt/sharcnet/openmpi/1.6.2/intel-debug/share/openmpi/openmpi-valgrind.supp&amp;lt;/tt&amp;gt;, however we have not observed any cases where this makes a difference yet.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Package website&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.valgrind.org&lt;br /&gt;
&lt;br /&gt;
[[Category:Software packages]]&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=10599</id>
		<title>VALGRIND</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=10599"/>
				<updated>2015-02-10T23:53:24Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Can't use LD_PRELOAD as required MPI library not in path (link against library instead)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=VALGRIND&lt;br /&gt;
|package_description=Memory debugger&lt;br /&gt;
|package_idnumber=132&lt;br /&gt;
}}&lt;br /&gt;
'''Valgrind''' is a powerful tool for analyzing programs, memory debugging, memory leak detection and profiling.  It is freely available under GNU license.&lt;br /&gt;
&lt;br /&gt;
Valgrind version 3.5.0 is available on most SHARCNET systems.&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Valgrind is a dynamic binary instrumentation framework that dynamically translates executables to add instrumentation and track all memory and register usages by a program.  The advantages of this approach are that&lt;br /&gt;
&lt;br /&gt;
* it can be directly run on any executable, and&lt;br /&gt;
* dynamic translation allows ultimate instrumentation&lt;br /&gt;
&lt;br /&gt;
while the disadvantages are&lt;br /&gt;
&lt;br /&gt;
* 5-100 x slow down depending on tool,&lt;br /&gt;
* 12-18 x increase in size of translated code, and&lt;br /&gt;
* corner cases may exist between translated code and original.&lt;br /&gt;
&lt;br /&gt;
Several tools have been built upon this framework.  These include&lt;br /&gt;
&lt;br /&gt;
* ''memcheck'' -  memory error detector&lt;br /&gt;
* ''cachegrind'' - cache and branch-prediction profiler&lt;br /&gt;
* ''callgrind'' - call-graph generating cache and branch prediction profiler&lt;br /&gt;
* ''helgrind'' - thread error detector&lt;br /&gt;
* ''DRD'' - thread error detector&lt;br /&gt;
* ''Massif'' - heap profiler&lt;br /&gt;
* ''DHAT'' - dynamic heap analysis tool&lt;br /&gt;
* ''SGCheck'' - experimental stack and global array overrun detector&lt;br /&gt;
* ''BBV'' - experimental basic block vector generation tool&lt;br /&gt;
&lt;br /&gt;
You are welcome to use any or all of these, but we have only used ''memcheck'' and ''cachegrind'' and only support ''memcheck''.&lt;br /&gt;
&lt;br /&gt;
= Usage =&lt;br /&gt;
&lt;br /&gt;
The primary used tool is ''memcheck''.  This is the default tool and the only one we discuss here.  Documentation for other tools can be found on the [http://www.valgrind.org valgrind website].  The memcheck tool detects several common memory errors&lt;br /&gt;
&lt;br /&gt;
* overrunning and underrunning heap blocks,&lt;br /&gt;
* overrunning top of stack,&lt;br /&gt;
* continuing to access released memory,&lt;br /&gt;
* using uninitialized values,&lt;br /&gt;
* incorrectly using memory copying routines,&lt;br /&gt;
* incorrectly paired allocation/release calls,&lt;br /&gt;
* relasing unallocated memory, and&lt;br /&gt;
* not releasing memory.&lt;br /&gt;
&lt;br /&gt;
We recommend running all new code under valgrind on small test cases (small due to the aforementioned ~10x slowdown).  This can save hours and hours of debugging.  Running the program under valgrind can be as simple as compiling with debugging information (adding the &amp;lt;tt&amp;gt;-g&amp;lt;/tt&amp;gt; flag) and running as &amp;lt;tt&amp;gt;valgrind &amp;lt;program&amp;gt; &amp;lt;arguements&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Serial code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
&lt;br /&gt;
  // Execution depends on uninitialized value&lt;br /&gt;
  if (array[4] &amp;lt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is negative\n&amp;quot;);&lt;br /&gt;
  else if (array[4] == 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is zero\n&amp;quot;);&lt;br /&gt;
  else if (array[4] &amp;gt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is positive\n&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    printf(&amp;quot;the results are special\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug.  Running this under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reports this&lt;br /&gt;
&lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400511: main (bug.c:7)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x40052C: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400536: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400551: main (bug.c:11)&lt;br /&gt;
&lt;br /&gt;
Note that valgrind only reports uninitialized values usage once they lead to non-determinism (i.e., when the program encounters a branch whose choice depends on the result of an uninitiated value).  This means you the first report you get is frequently not in the calculation done on the uninitialized values but rather the convergence test or print statement at the end of calculations (print statements contains a bunch of branches in order to handling printing of each different digit).&lt;br /&gt;
&lt;br /&gt;
== MPI code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' MPI code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;mpi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc,char *argv[]){&lt;br /&gt;
  int rank, size;&lt;br /&gt;
  int value;&lt;br /&gt;
&lt;br /&gt;
  MPI_Init(&amp;amp;argc, &amp;amp;argv);&lt;br /&gt;
&lt;br /&gt;
  MPI_Comm_rank(MPI_COMM_WORLD, &amp;amp;rank);&lt;br /&gt;
  MPI_Comm_size(MPI_COMM_WORLD, &amp;amp;size);&lt;br /&gt;
&lt;br /&gt;
  if (rank == 0 &amp;amp;&amp;amp; size &amp;gt; 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Irecv(&amp;amp;value, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 0;&lt;br /&gt;
    MPI_Wait (&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  }&lt;br /&gt;
  else if (rank == 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Isend(&amp;amp;value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 1;&lt;br /&gt;
    MPI_Wait(&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  } &lt;br /&gt;
&lt;br /&gt;
  MPI_Finalize();&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug and two race condition bugs around the use of value.&lt;br /&gt;
&lt;br /&gt;
# The first race condition is that rank==0 sets value=0 while at the same time doing a non-blocking receive into value (bug:16).&lt;br /&gt;
# The uninitialized value problem is that rank==1 starts a send of value to rank==0 without ever setting value (bug:22).&lt;br /&gt;
# The second race condition is that rank==1 sets value=1 while at the same time doing a non-blocking send of value (bug:23).&lt;br /&gt;
&lt;br /&gt;
=== Basic Functionality ===&lt;br /&gt;
&lt;br /&gt;
If you run this using the non-debug/valgrind openmpi valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load intel/12.1.3 openmpi/intel/1.6.2&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you are presumably getting a report about the uninitialized value, but it is burried in 55517 other bogus error messages.&lt;br /&gt;
&lt;br /&gt;
This solution to this is to link against the valgrind openmpi debug wrapper library too.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mpicc -Wall -g bug.c -L/usr/lib64/valgrind -lmpiwrap-amd64-linux -Xlinker -rpath=/usr/lib64/valgrind -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This now only reports one bogus error (a free on exit) and picks up the sending of the uninitialized value&lt;br /&gt;
&lt;br /&gt;
 ==27638== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27638==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27638==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27638==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27638==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27638==  Address 0x7fefff734 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Advanced Functionality ===&lt;br /&gt;
&lt;br /&gt;
Now, if on top of this, you also bring in the valgrind enabled openmpi debug library, things get really sweet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load intel/12.1.3 openmpi/intel-debug/1.6.2&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
LD_PRELOAD=/usr/lib64/valgrind/libmpiwrap-amd64-linux.so mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You still only get one bogus error (a free on exit) and all the bugs in the code are detected and reported&lt;br /&gt;
&lt;br /&gt;
 ==27774== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27774==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27774==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27774==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27774==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27773== Invalid write of size 4&lt;br /&gt;
 ==27773==    at 0x4026A0: main (bug.c:16)&lt;br /&gt;
 ==27773==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27774== Invalid write of size 4&lt;br /&gt;
 ==27774==    at 0x40271B: main (bug.c:23)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Suppression File ===&lt;br /&gt;
&lt;br /&gt;
There is also a valgrind suppression option &amp;lt;tt&amp;gt;--suppressions=/opt/sharcnet/openmpi/1.6.2/intel-debug/share/openmpi/openmpi-valgrind.supp&amp;lt;/tt&amp;gt;, however we have not observed any cases where this makes a difference yet.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Package website&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.valgrind.org&lt;br /&gt;
&lt;br /&gt;
[[Category:Software packages]]&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=MPIBLAST&amp;diff=10116</id>
		<title>MPIBLAST</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=MPIBLAST&amp;diff=10116"/>
				<updated>2014-11-17T17:00:07Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Add bioinformatics category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=MPIBLAST&lt;br /&gt;
|package_description=Parallel implementation of NCBI BLAST&lt;br /&gt;
|package_idnumber=55}}&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
The mpiblast module must be manually loaded before submitting any mpiblast jobs.  Two examples below &lt;br /&gt;
demonstrate how to setup and submit jobs to the mpi queue.&lt;br /&gt;
&lt;br /&gt;
=Version Selection=&lt;br /&gt;
&lt;br /&gt;
===All Clusters (except Guppy)===&lt;br /&gt;
&lt;br /&gt;
 module unload openmpi intel&lt;br /&gt;
 module load intel/12.1.3 openmpi/intel/1.6.2 mpiblast/1.6.0&lt;br /&gt;
&lt;br /&gt;
===Guppy Only===&lt;br /&gt;
&lt;br /&gt;
 module unload openmpi intel&lt;br /&gt;
 module load intel/11.0.083 openmpi/intel/1.4.2 mpiblast/1.6.0&lt;br /&gt;
&lt;br /&gt;
=Sample Problems=&lt;br /&gt;
&lt;br /&gt;
==DROSOPH==&lt;br /&gt;
&lt;br /&gt;
Copy sample problem files (fasta database and input) from the /opt/sharcnet &amp;lt;i&amp;gt;examples&amp;lt;/i&amp;gt; directory a directory under work as shown here.  The fasta database used in this example can be obtained as a guest  from NCBI here http://www.ncbi.nlm.nih.gov/guide/all/#downloads_  then clicking &amp;quot;FTP: FASTA BLAST Databases&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p /work/$USER/samples/mpiblast/test1&lt;br /&gt;
rm /work/$USER/samples/mpiblast/test1/*&lt;br /&gt;
cd /work/$USER/samples/mpiblast/test1&lt;br /&gt;
cp /opt/sharcnet/mpiblast/1.6.0/examples/drosoph.in drosoph.in&lt;br /&gt;
gunzip -c /opt/sharcnet/mpiblast/1.6.0/examples/drosoph.nt.gz &amp;gt; drosoph.nt.$USER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create a hidden configuration file using a text editor (such as vi) to define a Shared storage location between nodes and a Local storage directory available on each compute node as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[roberpj@hnd20:/work/$USER/samples/mpiblast/test1] vi .ncbirc&lt;br /&gt;
[NCBI]&lt;br /&gt;
Data=/opt/sharcnet/mpiblast/1.6.0/ncbi/data&lt;br /&gt;
[BLAST]&lt;br /&gt;
BLASTDB=/scratch/YourSharcnetUsername/mpiblasttest1&lt;br /&gt;
BLASTMAT=/work/YourSharcnetUsername/samples/mpiblast/test1&lt;br /&gt;
[mpiBLAST]&lt;br /&gt;
Shared=/scratch/YourSharcnetUsername/mpiblasttest1&lt;br /&gt;
Local=/tmp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Partition the database into 8 fragments into &amp;lt;i&amp;gt;/scratch/$USER/mpiblasttest1&amp;lt;/i&amp;gt; where they will be searched for when running a job in queue according to the &amp;lt;i&amp;gt;.ncbirc&amp;lt;/i&amp;gt; file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load mpiblast/1.6.0&lt;br /&gt;
mkdir /scratch/roberpj/mpiblasttest1&lt;br /&gt;
rm -f /scratch/$USER/mpiblasttest1/*&lt;br /&gt;
cd /work/$USER/samples/mpiblast/test1&lt;br /&gt;
&lt;br /&gt;
[roberpj@hnd20:/work/$USER/samples/mpiblast/test1] mpiformatdb -N 8 -i drosoph.nt.$USER -o T -p F -n /scratch/$USER/mpiblasttest1&lt;br /&gt;
Reading input file&lt;br /&gt;
Done, read 1534943 lines&lt;br /&gt;
Breaking drosoph.nt into 8 fragments&lt;br /&gt;
Executing: formatdb -p F -i drosoph.nt -N 8 -n /scratch/roberpj/mpiblasttest1/drosoph.nt -o T &lt;br /&gt;
Created 8 fragments.&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt; Please make sure the formatted database fragments are placed in /scratch/roberpj/mpiblasttest1/ before executing mpiblast. &amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[roberpj@hnd20:/scratch/roberpj/mpiblasttest1] ls&lt;br /&gt;
drosoph.nt.000.nhr  drosoph.nt.002.nin  drosoph.nt.004.nnd  drosoph.nt.006.nni&lt;br /&gt;
drosoph.nt.000.nin  drosoph.nt.002.nnd  drosoph.nt.004.nni  drosoph.nt.006.nsd&lt;br /&gt;
drosoph.nt.000.nnd  drosoph.nt.002.nni  drosoph.nt.004.nsd  drosoph.nt.006.nsi&lt;br /&gt;
drosoph.nt.000.nni  drosoph.nt.002.nsd  drosoph.nt.004.nsi  drosoph.nt.006.nsq&lt;br /&gt;
drosoph.nt.000.nsd  drosoph.nt.002.nsi  drosoph.nt.004.nsq  drosoph.nt.007.nhr&lt;br /&gt;
drosoph.nt.000.nsi  drosoph.nt.002.nsq  drosoph.nt.005.nhr  drosoph.nt.007.nin&lt;br /&gt;
drosoph.nt.000.nsq  drosoph.nt.003.nhr  drosoph.nt.005.nin  drosoph.nt.007.nnd&lt;br /&gt;
drosoph.nt.001.nhr  drosoph.nt.003.nin  drosoph.nt.005.nnd  drosoph.nt.007.nni&lt;br /&gt;
drosoph.nt.001.nin  drosoph.nt.003.nnd  drosoph.nt.005.nni  drosoph.nt.007.nsd&lt;br /&gt;
drosoph.nt.001.nnd  drosoph.nt.003.nni  drosoph.nt.005.nsd  drosoph.nt.007.nsi&lt;br /&gt;
drosoph.nt.001.nni  drosoph.nt.003.nsd  drosoph.nt.005.nsi  drosoph.nt.007.nsq&lt;br /&gt;
drosoph.nt.001.nsd  drosoph.nt.003.nsi  drosoph.nt.005.nsq  drosoph.nt.dbs&lt;br /&gt;
drosoph.nt.001.nsi  drosoph.nt.003.nsq  drosoph.nt.006.nhr  drosoph.nt.mbf&lt;br /&gt;
drosoph.nt.001.nsq  drosoph.nt.004.nhr  drosoph.nt.006.nin  drosoph.nt.nal&lt;br /&gt;
drosoph.nt.002.nhr  drosoph.nt.004.nin  drosoph.nt.006.nnd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Submit a short job with a 15m time limit on n=16 cores calculate by taking N=8 fragments + 8.  If all goes well output results will be written to &amp;lt;i&amp;gt;drosoph.out&amp;lt;/i&amp;gt; and the execution time will appear in ofile%J where %J is the job number:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[roberpj@hnd20:/work/$USER/samples/mpiblast/test1]&lt;br /&gt;
sqsub -r 15m -n 106 -q mpi --mpp=1G -o ofile%J mpiblast -d drosoph.nt.$USER -i drosoph.in&lt;br /&gt;
    -p blastn -o drosoph.out --use-parallel-write --use-virtual-frags&lt;br /&gt;
submitted as jobid 6966896&lt;br /&gt;
&lt;br /&gt;
[roberpj@hnd20:/work/roberpj/samples/mpiblast/test1] cat ofile6966896.hnd50 &lt;br /&gt;
Total Execution Time: 1.80031&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When submitting a mpiblast job on a cluster such as goblin that doesnt have an inifiniband interconnect better performance (at least double speedup) will be achieved running the mpi job on one compute node.  For regular users of non-contributed hardware typically specify &amp;quot;-n 8&amp;quot; to reflect the max number of cores on a single node:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sqsub -r 15m -n 8 -N 1 -q mpi --mpp=4G -o ofile%J mpiblast -d drosoph.nt -i drosoph.in&lt;br /&gt;
           -p blastn -o drosoph.out --use-parallel-write --use-virtual-frags&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sample output results computed previously with BLASTN 2.2.15 [Oct-15-2006] are included in &amp;lt;i&amp;gt;/opt/sharcnet/mpiblast/1.6.0/examples/ROSOPH.out&amp;lt;/i&amp;gt; to compare your newly generated &amp;lt;i&amp;gt;drosoph.out&amp;lt;/i&amp;gt; file with.&lt;br /&gt;
&lt;br /&gt;
==UNIGENE==&lt;br /&gt;
&lt;br /&gt;
The main purpose of this example is to illustrate some additional options and switchs that maybe useful for debugging and for dealing with larger databases as described in official detail at http://www.mpiblast.org/Docs/Guide.  The fasta database used in this example can also be downloaded from http://www.ncbi.nlm.nih.gov/guide/all/#downloads_ as a guest by clicking &amp;quot;FTP: UniGene&amp;quot; then entering the &amp;quot;Homo_sapiens&amp;quot; sub-directory.  More information about UniGene alignments can be found at https://cgwb.nci.nih.gov/cgi-bin/hgTrackUi?hgsid=95443&amp;amp;c=chr1&amp;amp;g=uniGene_3 .  As with Example1 above, for convenience all required files can simply be copied from the /opt/sharcnet &amp;lt;i&amp;gt;examples&amp;lt;/i&amp;gt; subdirectory to work as shown here:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir /work/$USER/samples/mpiblast/test2&lt;br /&gt;
rm -f /work/$USER/samples/mpiblast/test2/*&lt;br /&gt;
cd /work/$USER/samples/mpiblast/test2&lt;br /&gt;
cp /opt/sharcnet/mpiblast/1.6.0/examples/il2ra.in il2ra.in&lt;br /&gt;
gunzip -c /opt/sharcnet/mpiblast/1.6.0/examples/Hs.seq.uniq.gz &amp;gt; Hs.seq.$USER&lt;br /&gt;
&lt;br /&gt;
[roberpj@orc-login2:/work/roberpj/samples/mpiblast/test2] ls&lt;br /&gt;
Hs.seq.roberpj  il2ra.in&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create a hidden configuration file using a text editor (such as vi) to define a Shared storage location between nodes and a Local storage directory available on each compute node as followw.  Note that the ncbi/data directory is not used in this example and hence can be omitted.  If the Local and Shared directories are the same replace &amp;lt;b&amp;gt;--copy-via=mpi&amp;lt;/b&amp;gt; with &amp;lt;b&amp;gt;--copy-via=none&amp;lt;/b&amp;gt; as will be demonstrated in the below sqsub commands.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[username@orc-login1:/work/$USER/samples/mpiblast/test2] vi .ncbirc&lt;br /&gt;
[NCBI]&lt;br /&gt;
Data=/opt/sharcnet/mpiblast/1.6.0/ncbi/data&lt;br /&gt;
[BLAST]&lt;br /&gt;
BLASTDB=/work/YourSharcnetUsername/mpiblasttest2&lt;br /&gt;
BLASTMAT=/work/YourSharcnetUsername/samples/mpiblast/test2&lt;br /&gt;
[mpiBLAST]&lt;br /&gt;
Shared=/work/YourSharcnetUsername/mpiblasttest2&lt;br /&gt;
Local=/tmp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Again partition the database into 8 fragments into &amp;lt;i&amp;gt;/work/$USER/mpiblasttest2&amp;lt;/i&amp;gt; where they will be searched for when a job runs in the queue according to the &amp;lt;i&amp;gt;.ncbirc&amp;lt;/i&amp;gt; file, first removing previous partitioning if any such files exist.  For this example assume $USER=roberpj however be sure to replace with your username!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load mpiblast/1.6.0&lt;br /&gt;
mkdir -p /work/$USER/mpiblasttest2&lt;br /&gt;
rm -f /work/$USER/mpiblasttest2/*&lt;br /&gt;
cd /work/$USER/samples/mpiblast/test2&lt;br /&gt;
&lt;br /&gt;
[roberpj@orc-login1:/work/roberpj/samples/mpiblast/test2] mpiformatdb -N 8 -i Hs.seq.$USER -o T -p F -n /work/roberpj/mpiblasttest2&lt;br /&gt;
Reading input file&lt;br /&gt;
Done, read 2348651 lines&lt;br /&gt;
Breaking Hs.seq.roberpj into 8 fragments&lt;br /&gt;
Executing: formatdb -p F -i Hs.seq.roberpj -N 8 -n /work/roberpj/mpiblasttest2/Hs.seq.roberpj -o T &lt;br /&gt;
Created 8 fragments.&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt; Please make sure the formatted database fragments are placed in /work/roberpj/mpiblasttest2/ before executing mpiblast. &amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[roberpj@orc-login1:/work/roberpj/samples/mpiblast/test1] ls&lt;br /&gt;
formatdb.log  Hs.seq.roberpj  il2ra.in&lt;br /&gt;
&lt;br /&gt;
[roberpj@orc-login1:/work/roberpj/mpiblasttest2] ls&lt;br /&gt;
Hs.seq.roberpj.000.nhr  Hs.seq.roberpj.002.nin  Hs.seq.roberpj.004.nnd  Hs.seq.roberpj.006.nni&lt;br /&gt;
Hs.seq.roberpj.000.nin  Hs.seq.roberpj.002.nnd  Hs.seq.roberpj.004.nni  Hs.seq.roberpj.006.nsd&lt;br /&gt;
Hs.seq.roberpj.000.nnd  Hs.seq.roberpj.002.nni  Hs.seq.roberpj.004.nsd  Hs.seq.roberpj.006.nsi&lt;br /&gt;
Hs.seq.roberpj.000.nni  Hs.seq.roberpj.002.nsd  Hs.seq.roberpj.004.nsi  Hs.seq.roberpj.006.nsq&lt;br /&gt;
Hs.seq.roberpj.000.nsd  Hs.seq.roberpj.002.nsi  Hs.seq.roberpj.004.nsq  Hs.seq.roberpj.007.nhr&lt;br /&gt;
Hs.seq.roberpj.000.nsi  Hs.seq.roberpj.002.nsq  Hs.seq.roberpj.005.nhr  Hs.seq.roberpj.007.nin&lt;br /&gt;
Hs.seq.roberpj.000.nsq  Hs.seq.roberpj.003.nhr  Hs.seq.roberpj.005.nin  Hs.seq.roberpj.007.nnd&lt;br /&gt;
Hs.seq.roberpj.001.nhr  Hs.seq.roberpj.003.nin  Hs.seq.roberpj.005.nnd  Hs.seq.roberpj.007.nni&lt;br /&gt;
Hs.seq.roberpj.001.nin  Hs.seq.roberpj.003.nnd  Hs.seq.roberpj.005.nni  Hs.seq.roberpj.007.nsd&lt;br /&gt;
Hs.seq.roberpj.001.nnd  Hs.seq.roberpj.003.nni  Hs.seq.roberpj.005.nsd  Hs.seq.roberpj.007.nsi&lt;br /&gt;
Hs.seq.roberpj.001.nni  Hs.seq.roberpj.003.nsd  Hs.seq.roberpj.005.nsi  Hs.seq.roberpj.007.nsq&lt;br /&gt;
Hs.seq.roberpj.001.nsd  Hs.seq.roberpj.003.nsi  Hs.seq.roberpj.005.nsq  Hs.seq.roberpj.dbs&lt;br /&gt;
Hs.seq.roberpj.001.nsi  Hs.seq.roberpj.003.nsq  Hs.seq.roberpj.006.nhr  Hs.seq.roberpj.mbf&lt;br /&gt;
Hs.seq.roberpj.001.nsq  Hs.seq.roberpj.004.nhr  Hs.seq.roberpj.006.nin  Hs.seq.roberpj.nal&lt;br /&gt;
Hs.seq.roberpj.002.nhr  Hs.seq.roberpj.004.nin  Hs.seq.roberpj.006.nnd   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Submit a couple of short jobs 15m time limit.  If all goes well output results will be written to &amp;lt;i&amp;gt;biobrewA.out&amp;lt;/i&amp;gt; and &amp;lt;i&amp;gt;biobrewB.out&amp;lt;/i&amp;gt; and the execution time appear in corresponding ofile%J's where %J is the job number as per usual.  In these examples we will submit the job from a saw specific directory which can be copied from test2 as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[roberpj@saw-login1:~] module load mpiblast/1.6.0&lt;br /&gt;
[roberpj@saw-login1:~] cd /work/roberpj/samples/mpiblast&lt;br /&gt;
[roberpj@saw-login1:/work/roberpj/samples/mpiblast] cp -a test2 test2.saw&lt;br /&gt;
&lt;br /&gt;
[roberpj@saw-login1:/work/roberpj/samples/mpiblast/test2.saw] vi .ncbirc&lt;br /&gt;
[roberpj@saw-login1:/work/roberpj/samples/mpiblast/test2.saw] cat .ncbirc | grep BLASTMAT&lt;br /&gt;
BLASTMAT=/work/roberpj/samples/mpiblast/test2.saw&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A) Submit job with profile time option choosing n=24 (8 fragments + 8 or greater):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[roberpj@saw-login1:/work/roberpj/samples/mpiblast/test2.saw] rm -f oTime*;&lt;br /&gt;
    sqsub -r 15m -n 24 -q mpi -o ofile%J mpiblast  --use-parallel-write --copy-via=mpi&lt;br /&gt;
       -d Hs.seq.roberpj -i il2ra.in -p blastn -o biobrew.out --time-profile=oTime&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
B) Usage of the debug option again choosing n=16 (8 fragments + 8 or greater):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[roberpj@saw-login1:/work/roberpj/samples/mpiblast/test2.saw]  rm -f oLog*;&lt;br /&gt;
    sqsub -r 15m -n 16 -q mpi -o ofile%J mpiblast --use-parallel-write --copy-via=none&lt;br /&gt;
        -d Hs.seq.$USER -i il2ra.in -p blastn -o biobrew.out --debug=oLog&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally compare &amp;lt;i&amp;gt;/opt/sharcnet/mpiblast/1.6.0/examples/BIOBREW.out&amp;lt;/i&amp;gt; computed previously with BLASTN 2.2.15 [Oct-15-2006] with your newly generated &amp;lt;i&amp;gt;biobrew.out&amp;lt;/i&amp;gt; output file to verify the results and submit a ticket if there are any problems!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;SUPPORTED PROGRAMS IN MPIBLAST&amp;lt;/U&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As described in http://www.mpiblast.org/Docs/FAQ mpiblast supports the standard blast programs http://www.ncbi.nlm.nih.gov/BLAST/blast_program.shtml which are reproduced here for reference:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
blastp:     Compares an amino acid query sequence against a protein sequence database.&lt;br /&gt;
blastn:     Compares a nucleotide query sequence against a nucleotide sequence database.&lt;br /&gt;
blastx:     Compares a nucleotide query sequence translated in all reading frames against&lt;br /&gt;
            a protein sequence database.&lt;br /&gt;
tblastn:    Compares a protein query sequence against a nucleotide sequence database&lt;br /&gt;
            dynamically translated in all reading frames.&lt;br /&gt;
tblastx:    Compares the six-frame translations of a nucleotide query sequence against&lt;br /&gt;
            the six-frame translations of a nucleotide sequence database.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;MPIBLAST BINARIES OPTIONS&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[roberpj@orc-login1:/opt/sharcnet/mpiblast/1.6.0/bin] ./mpiblast -help&lt;br /&gt;
mpiBLAST requires the following options: -d [database] -i [query file] -p [blast program name]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[roberpj@orc-login1:/opt/sharcnet/mpiblast/1.6.0/bin] ./mpiformatdb --help&lt;br /&gt;
Executing: formatdb - &lt;br /&gt;
&lt;br /&gt;
formatdb 2.2.20   arguments:&lt;br /&gt;
&lt;br /&gt;
  -t  Title for database file [String]  Optional&lt;br /&gt;
  -i  Input file(s) for formatting [File In]  Optional&lt;br /&gt;
  -l  Logfile name: [File Out]  Optional&lt;br /&gt;
    default = formatdb.log&lt;br /&gt;
  -p  Type of file&lt;br /&gt;
         T - protein   &lt;br /&gt;
         F - nucleotide [T/F]  Optional&lt;br /&gt;
    default = T&lt;br /&gt;
  -o  Parse options&lt;br /&gt;
         T - True: Parse SeqId and create indexes.&lt;br /&gt;
         F - False: Do not parse SeqId. Do not create indexes.&lt;br /&gt;
 [T/F]  Optional&lt;br /&gt;
    default = F&lt;br /&gt;
  -a  Input file is database in ASN.1 format (otherwise FASTA is expected)&lt;br /&gt;
         T - True, &lt;br /&gt;
         F - False.&lt;br /&gt;
 [T/F]  Optional&lt;br /&gt;
    default = F&lt;br /&gt;
  -b  ASN.1 database in binary mode&lt;br /&gt;
         T - binary, &lt;br /&gt;
         F - text mode.&lt;br /&gt;
 [T/F]  Optional&lt;br /&gt;
    default = F&lt;br /&gt;
  -e  Input is a Seq-entry [T/F]  Optional&lt;br /&gt;
    default = F&lt;br /&gt;
  -n  Base name for BLAST files [String]  Optional&lt;br /&gt;
  -v  Database volume size in millions of letters [Integer]  Optional&lt;br /&gt;
    default = 4000&lt;br /&gt;
  -s  Create indexes limited only to accessions - sparse [T/F]  Optional&lt;br /&gt;
    default = F&lt;br /&gt;
  -V  Verbose: check for non-unique string ids in the database [T/F]  Optional&lt;br /&gt;
    default = F&lt;br /&gt;
  -L  Create an alias file with this name&lt;br /&gt;
        use the gifile arg (below) if set to calculate db size&lt;br /&gt;
        use the BLAST db specified with -i (above) [File Out]  Optional&lt;br /&gt;
  -F  Gifile (file containing list of gi's) [File In]  Optional&lt;br /&gt;
  -B  Binary Gifile produced from the Gifile specified above [File Out]  Optional&lt;br /&gt;
  -T  Taxid file to set the taxonomy ids in ASN.1 deflines [File In]  Optional&lt;br /&gt;
  -N  Number of database volumes [Integer]  Optional&lt;br /&gt;
    default = 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=General Notes=&lt;br /&gt;
&lt;br /&gt;
==Issue1: Jobs Fail to Start==&lt;br /&gt;
&lt;br /&gt;
If the following error message occurs it maybe necessary to stop all mpiblast jobs you are running on the cluster and clear&lt;br /&gt;
out all the files from /tmp then submit your job again.  In the case of Example2 above the following steps work to resolve the problem, where the nodes from the last run job are used red[7-14.  Should there be any questions please open a problem ticket.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Purging Job Node Subset (redfin)&lt;br /&gt;
 pdsh -w red[7-14] ls /tmp/Hs*     (confirm existence of file from previous runs)&lt;br /&gt;
 pdsh -w red[7-14] rm -f /tmp/Hs*&lt;br /&gt;
 pdsh -w red[7-14] ls /tmp/Hs*     (confirm all files from previous runs removed)&lt;br /&gt;
&lt;br /&gt;
Purging Full Cluster (hound)&lt;br /&gt;
pdsh -w hnd[1-18] -f 4 rm -f /tmp/Hs*&lt;br /&gt;
pdsh -w hnd[1-18] -f 4 ls /tmp/Hs*&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[roberpj@red-admin:/work/roberpj/samples/mpiblast/test2.red4] cat ofile489214.red-admin.redfin.sharcnet&lt;br /&gt;
8       0.577904        Bailing out with signal 11&lt;br /&gt;
--------------------------------------------------------------------------&lt;br /&gt;
MPI_ABORT was invoked on rank 8 in communicator MPI_COMM_WORLD&lt;br /&gt;
with errorcode 0.&lt;br /&gt;
&lt;br /&gt;
NOTE: invoking MPI_ABORT causes Open MPI to kill all MPI processes.&lt;br /&gt;
You may or may not see output from other processes, depending on&lt;br /&gt;
exactly when Open MPI kills them.&lt;br /&gt;
--------------------------------------------------------------------------&lt;br /&gt;
20      0.577719        Bailing out with signal 11&lt;br /&gt;
0       0.591128        Bailing out with signal 15&lt;br /&gt;
[red14:09194] [[36424,0],0]-[[36424,1],0] mca_oob_tcp_msg_recv: readv failed: Connection reset by peer (104)&lt;br /&gt;
1       0.591327        Bailing out with signal 15&lt;br /&gt;
etc&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issue2: Jobs Run for a While then Die==&lt;br /&gt;
&lt;br /&gt;
The solution here is to filter the input sequence file. For reasons yet understood the presence of repeat sections results in many thousands of WARNING and ERROR messages rapidly written to the &amp;quot;sqsub -o ofile&amp;quot; output file presumably as mpiblast ignores sequences before eventually diing after several hours, or possibly days.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cat  ofile1635556.saw-admin.saw.sharcnet | grep &amp;quot;WARNING\|ERROR&amp;quot; | wc -l&lt;br /&gt;
10560&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cat ofile1635556.saw-admin.saw.sharcnet&lt;br /&gt;
Selenocysteine (U) at position 60 replaced by X&lt;br /&gt;
Selenocysteine (U) at position 42 replaced by X&lt;br /&gt;
[blastall] WARNING:  [000.000]  NODE_84_length_162_cov_46.259258_1_192_-: SetUpBlastSearch failed.&lt;br /&gt;
[blastall] ERROR:  [000.000]  NODE_84_length_162_cov_46.259258_1_192_-: BLASTSetUpSearch: Unable to calculate Karlin-Altschul params, check query sequence&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;&amp;lt; snipped out ~10000 similar WARNING and ERROR messages from this example &amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
[blastall] WARNING:  [000.000]  NODE_65409_length_87_cov_2.367816_1_77_+: SetUpBlastSearch failed.&lt;br /&gt;
[blastall] ERROR:  [000.000]  NODE_65409_length_87_cov_2.367816_1_77_+: BLASTSetUpSearch: Unable to calculate Karlin-Altschul params, check query sequence&lt;br /&gt;
Selenocysteine (U) at position 61 replaced by X&lt;br /&gt;
Selenocysteine (U) at position 62 replaced by X&lt;br /&gt;
Selenocysteine (U) at position 34 replaced by X&lt;br /&gt;
Selenocysteine (U) at position 1058 replaced by X&lt;br /&gt;
--------------------------------------------------------------------------&lt;br /&gt;
mpirun noticed that process rank 52 with PID 30067 on node saw214 exited on signal 9 (Killed).&lt;br /&gt;
--------------------------------------------------------------------------&lt;br /&gt;
1618    17      651     62909.3 Bailing out with signal 15&lt;br /&gt;
14      3       62909.3 Bailing out with signal 15&lt;br /&gt;
19      15      62909.3 Bailing out with signal 1536    5       7       62909.312       62909.310       62909.3 Bailing out with signal 1547    21      62909.3 Bailing out with signal 159  62909.3 Bailing out with signal 15&lt;br /&gt;
45      62909.3 Bailing out with signal 1525    62909.3 Bailing out with signal 158     62909.3 Bailing out with signal 15&lt;br /&gt;
50      62909.3 Bailing out with signal 1522    62909.3 Bailing out with signal 15&lt;br /&gt;
11      62909.3 Bailing out with signal 15&lt;br /&gt;
48      62909.323       62909.3 Bailing out with signal 15&lt;br /&gt;
        Bailing out with signal 15&lt;br /&gt;
46      62909.3 Bailing out with signal 15&lt;br /&gt;
etc&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o MPIBLAST Homepage&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.mpiblast.org/&lt;br /&gt;
&lt;br /&gt;
o MPIBLAST Version History&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.mpiblast.org/Downloads/Version-History&lt;br /&gt;
&lt;br /&gt;
[[Category:Bioinformatics]]&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=File:Seminar-2014-04-16-slides.pdf&amp;diff=8421</id>
		<title>File:Seminar-2014-04-16-slides.pdf</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=File:Seminar-2014-04-16-slides.pdf&amp;diff=8421"/>
				<updated>2014-04-16T19:13:09Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=7504</id>
		<title>VALGRIND</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=VALGRIND&amp;diff=7504"/>
				<updated>2013-10-07T15:25:20Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Add instructions and examples for serial and MPI code&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Software&lt;br /&gt;
|package_name=VALGRIND&lt;br /&gt;
|package_description=Memory debugger&lt;br /&gt;
|package_idnumber=132&lt;br /&gt;
}}&lt;br /&gt;
'''Valgrind''' is a powerful tool for analyzing programs, memory debugging, memory leak detection and profiling.  It is freely available under GNU license.&lt;br /&gt;
&lt;br /&gt;
Valgrind version 3.5.0 is available on most SHARCNET systems.&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Valgrind is a dynamic binary instrumentation framework that dynamically translates executables to add instrumentation and track all memory and register usages by a program.  The advantages of this approach are that&lt;br /&gt;
&lt;br /&gt;
* it can be directly run on any executable, and&lt;br /&gt;
* dynamic translation allows ultimate instrumentation&lt;br /&gt;
&lt;br /&gt;
while the disadvantages are&lt;br /&gt;
&lt;br /&gt;
* 5-100 x slow down depending on tool,&lt;br /&gt;
* 12-18 x increase in size of translated code, and&lt;br /&gt;
* corner cases may exist between translated code and original.&lt;br /&gt;
&lt;br /&gt;
Several tools have been built upon this framework.  These include&lt;br /&gt;
&lt;br /&gt;
* ''memcheck'' -  memory error detector&lt;br /&gt;
* ''cachegrind'' - cache and branch-prediction profiler&lt;br /&gt;
* ''callgrind'' - call-graph generating cache and branch prediction profiler&lt;br /&gt;
* ''helgrind'' - thread error detector&lt;br /&gt;
* ''DRD'' - thread error detector&lt;br /&gt;
* ''Massif'' - heap profiler&lt;br /&gt;
* ''DHAT'' - dynamic heap analysis tool&lt;br /&gt;
* ''SGCheck'' - experimental stack and global array overrun detector&lt;br /&gt;
* ''BBV'' - experimental basic block vector generation tool&lt;br /&gt;
&lt;br /&gt;
You are welcome to use any or all of these, but we have only used ''memcheck'' and ''cachegrind'' and only support ''memcheck''.&lt;br /&gt;
&lt;br /&gt;
= Usage =&lt;br /&gt;
&lt;br /&gt;
The primary used tool is ''memcheck''.  This is the default tool and the only one we discuss here.  Documentation for other tools can be found on the [http://www.valgrind.org valgrind website].  The memcheck tool detects several common memory errors&lt;br /&gt;
&lt;br /&gt;
* overrunning and underrunning heap blocks,&lt;br /&gt;
* overrunning top of stack,&lt;br /&gt;
* continuing to access released memory,&lt;br /&gt;
* using uninitialized values,&lt;br /&gt;
* incorrectly using memory copying routines,&lt;br /&gt;
* incorrectly paired allocation/release calls,&lt;br /&gt;
* relasing unallocated memory, and&lt;br /&gt;
* not releasing memory.&lt;br /&gt;
&lt;br /&gt;
We recommend running all new code under valgrind on small test cases (small due to the aforementioned ~10x slowdown).  This can save hours and hours of debugging.  Running the program under valgrind can be as simple as compiling with debugging information (adding the &amp;lt;tt&amp;gt;-g&amp;lt;/tt&amp;gt; flag) and running as &amp;lt;tt&amp;gt;valgrind &amp;lt;program&amp;gt; &amp;lt;arguements&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Serial code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  double array[10];&lt;br /&gt;
&lt;br /&gt;
  // Execution depends on uninitialized value&lt;br /&gt;
  if (array[4] &amp;lt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is negative\n&amp;quot;);&lt;br /&gt;
  else if (array[4] == 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is zero\n&amp;quot;);&lt;br /&gt;
  else if (array[4] &amp;gt; 0.0)&lt;br /&gt;
    printf(&amp;quot;the results is positive\n&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    printf(&amp;quot;the results are special\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug.  Running this under valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cc -Wall -g bug.c -o bug&lt;br /&gt;
valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reports this&lt;br /&gt;
&lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400511: main (bug.c:7)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x40052C: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400536: main (bug.c:9)&lt;br /&gt;
 ==5955== &lt;br /&gt;
 ==5955== Conditional jump or move depends on uninitialised value(s)&lt;br /&gt;
 ==5955==    at 0x400551: main (bug.c:11)&lt;br /&gt;
&lt;br /&gt;
Note that valgrind only reports uninitialized values usage once they lead to non-determinism (i.e., when the program encounters a branch whose choice depends on the result of an uninitiated value).  This means you the first report you get is frequently not in the calculation done on the uninitialized values but rather the convergence test or print statement at the end of calculations (print statements contains a bunch of branches in order to handling printing of each different digit).&lt;br /&gt;
&lt;br /&gt;
== MPI code ==&lt;br /&gt;
&lt;br /&gt;
Consider the following ''bug.c'' MPI code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;mpi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc,char *argv[]){&lt;br /&gt;
  int rank, size;&lt;br /&gt;
  int value;&lt;br /&gt;
&lt;br /&gt;
  MPI_Init(&amp;amp;argc, &amp;amp;argv);&lt;br /&gt;
&lt;br /&gt;
  MPI_Comm_rank(MPI_COMM_WORLD, &amp;amp;rank);&lt;br /&gt;
  MPI_Comm_size(MPI_COMM_WORLD, &amp;amp;size);&lt;br /&gt;
&lt;br /&gt;
  if (rank == 0 &amp;amp;&amp;amp; size &amp;gt; 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Irecv(&amp;amp;value, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 0;&lt;br /&gt;
    MPI_Wait (&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  }&lt;br /&gt;
  else if (rank == 1) {&lt;br /&gt;
    MPI_Request request;&lt;br /&gt;
&lt;br /&gt;
    MPI_Isend(&amp;amp;value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &amp;amp;request);&lt;br /&gt;
    value = 1;&lt;br /&gt;
    MPI_Wait(&amp;amp;request, MPI_STATUS_IGNORE);&lt;br /&gt;
  } &lt;br /&gt;
&lt;br /&gt;
  MPI_Finalize();&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It has an uninitialized value bug and two race condition bugs around the use of value.&lt;br /&gt;
&lt;br /&gt;
# The first race condition is that rank==0 sets value=0 while at the same time doing a non-blocking receive into value (bug:16).&lt;br /&gt;
# The uninitialized value problem is that rank==1 starts a send of value to rank==0 without ever setting value (bug:22).&lt;br /&gt;
# The second race condition is that rank==1 sets value=1 while at the same time doing a non-blocking send of value (bug:23).&lt;br /&gt;
&lt;br /&gt;
=== Basic Functionality ===&lt;br /&gt;
&lt;br /&gt;
If you run this using the non-debug/valgrind openmpi valgrind&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load intel/12.1.3 openmpi/intel/1.6.2&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you are presumably getting a report about the uninitialized value, but it is burried in 55517 other bogus error messages.&lt;br /&gt;
&lt;br /&gt;
This solution to this is to LD_PRELOAD the valgrind openmpi debug wrapper library.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
LD_PRELOAD=/usr/lib64/valgrind/libmpiwrap-amd64-linux.so mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This now only reports one bogus error (a free on exit) and picks up the sending of the uninitialized value&lt;br /&gt;
&lt;br /&gt;
 ==27638== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27638==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27638==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27638==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27638==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27638==  Address 0x7fefff734 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Advanced Functionality ===&lt;br /&gt;
&lt;br /&gt;
Now, if on top of this, you also bring in the valgrind enabled openmpi debug library, things get really sweet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module unload intel openmpi&lt;br /&gt;
module load intel/12.1.3 openmpi/intel-debug/1.6.2&lt;br /&gt;
mpicc -Wall -g bug.c -o bug&lt;br /&gt;
LD_PRELOAD=/usr/lib64/valgrind/libmpiwrap-amd64-linux.so mpirun -np 2 valgrind ./bug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You still only get one bogus error (a free on exit) and all the bugs in the code are detected and reported&lt;br /&gt;
&lt;br /&gt;
 ==27774== Uninitialised byte(s) found during client check request&lt;br /&gt;
 ==27774==    at 0x4E3641D: check_mem_is_defined_untyped (libmpiwrap.c:952)&lt;br /&gt;
 ==27774==    by 0x4E5BBC5: generic_Isend (libmpiwrap.c:908)&lt;br /&gt;
 ==27774==    by 0x4E5BEE9: PMPI_Isend (libmpiwrap.c:1393)&lt;br /&gt;
 ==27774==    by 0x402713: main (bug.c:22)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27773== Invalid write of size 4&lt;br /&gt;
 ==27773==    at 0x4026A0: main (bug.c:16)&lt;br /&gt;
 ==27773==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
 &lt;br /&gt;
 ==27774== Invalid write of size 4&lt;br /&gt;
 ==27774==    at 0x40271B: main (bug.c:23)&lt;br /&gt;
 ==27774==  Address 0x7fefff6f4 is on thread 1's stack&lt;br /&gt;
&lt;br /&gt;
=== Suppression File ===&lt;br /&gt;
&lt;br /&gt;
There is also a valgrind suppression option &amp;lt;tt&amp;gt;--suppressions=/opt/sharcnet/openmpi/1.6.2/intel-debug/share/openmpi/openmpi-valgrind.supp&amp;lt;/tt&amp;gt;, however we have not observed any cases where this makes a difference yet.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
o Package website&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.valgrind.org&lt;br /&gt;
&lt;br /&gt;
[[Category:Software packages]]&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=MediaWiki:MenuSidebar&amp;diff=2368</id>
		<title>MediaWiki:MenuSidebar</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=MediaWiki:MenuSidebar&amp;diff=2368"/>
				<updated>2010-11-05T15:24:55Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Update links now that MediaWiki code is supported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Common Destinations&lt;br /&gt;
** [[Knowledge Base]]&lt;br /&gt;
** [http://www.sharcnet.ca/my SHARCNET Web Portal]&lt;br /&gt;
* Clusters Facilities&lt;br /&gt;
** [[Main_Page#SHARCNET|Working with the Clusters]]&lt;br /&gt;
** [[Main_Page#Programming|Programming the Clusters]]&lt;br /&gt;
* Other Facilities&lt;br /&gt;
** [[Main_Page#Visualization|Visualization]]&lt;br /&gt;
** [[Main_Page#AccessGrid|Video Conferencing]]&lt;br /&gt;
* Domain Specific Portals&lt;br /&gt;
** [[Astrophysics]]&lt;br /&gt;
** [[Bioinformatics]]&lt;br /&gt;
** [[Digital Humanities]]&lt;br /&gt;
** [[Chemistry, Biochemistry and Biophysics]]&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=MediaWiki:Sidebar&amp;diff=2085</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=MediaWiki:Sidebar&amp;diff=2085"/>
				<updated>2010-08-06T17:57:16Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Put back to the same in order to avoid toolbars floating to the top&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Common Destinations&lt;br /&gt;
** Knowledge_Base|Knowledge Base&lt;br /&gt;
** http://www.sharcnet.ca/my|SHARCNET Web Portal&lt;br /&gt;
* Clusters Facilities&lt;br /&gt;
** Main_Page#SHARCNET|Working with the Clusters&lt;br /&gt;
** Main_Page#Programming|Programming the Clusters&lt;br /&gt;
* Other Facilities&lt;br /&gt;
** Main_Page#Visualization|Visualization&lt;br /&gt;
** Main_Page#AccessGrid|Video Conferencing&lt;br /&gt;
* Domain Specific Portals&lt;br /&gt;
** Astrophysics|Astrophysics&lt;br /&gt;
** Bioinformatics|Bioinformatics&lt;br /&gt;
** Digital_Humanities|Digital Humanities&lt;br /&gt;
** Chemistry,_Biochemistry_and_Biophysics|Chemistry, Biochemistry and Biophysics&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=MediaWiki:Sidebar&amp;diff=2084</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=MediaWiki:Sidebar&amp;diff=2084"/>
				<updated>2010-08-06T17:50:11Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Screws up if entirely blank, try generic ones at bottom&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=MediaWiki:Sidebar&amp;diff=2083</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=MediaWiki:Sidebar&amp;diff=2083"/>
				<updated>2010-08-06T17:48:54Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: We are using the MenuSideBar extension instead&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=MediaWiki:MenuSidebar&amp;diff=2082</id>
		<title>MediaWiki:MenuSidebar</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=MediaWiki:MenuSidebar&amp;diff=2082"/>
				<updated>2010-08-06T17:44:52Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Duplicate new SideBar menu&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Common Destinations&lt;br /&gt;
** Knowledge_Base|Knowledge Base&lt;br /&gt;
** http://www.sharcnet.ca/my|SHARCNET Web Portal&lt;br /&gt;
* Clusters Facilities&lt;br /&gt;
** Main_Page#SHARCNET|Working with the Clusters&lt;br /&gt;
** Main_Page#Programming|Programming the Clusters&lt;br /&gt;
* Other Facilities&lt;br /&gt;
** Main_Page#Visualization|Visualization&lt;br /&gt;
** Main_Page#AccessGrid|Video Conferencing&lt;br /&gt;
* Domain Specific Portals&lt;br /&gt;
** Astrophysics|Astrophysics&lt;br /&gt;
** Bioinformatics|Bioinformatics&lt;br /&gt;
** Digital_Humanities|Digital Humanities&lt;br /&gt;
** Chemistry,_Biochemistry_and_Biophysics|Chemistry, Biochemistry and Biophysics&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=MediaWiki:MenuSidebar&amp;diff=2081</id>
		<title>MediaWiki:MenuSidebar</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=MediaWiki:MenuSidebar&amp;diff=2081"/>
				<updated>2010-08-06T17:32:52Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Don't use for now (just use Sidebar instead)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=MediaWiki:Sidebar&amp;diff=2070</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=MediaWiki:Sidebar&amp;diff=2070"/>
				<updated>2010-08-06T17:12:29Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: A possible alternative sidebar&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Common Destinations&lt;br /&gt;
** Knowledge_Base|Knowledge Base&lt;br /&gt;
** http://www.sharcnet.ca/my|SHARCNET Web Portal&lt;br /&gt;
* Clusters Facilities&lt;br /&gt;
** Main_Page#SHARCNET|Working with the Clusters&lt;br /&gt;
** Main_Page#Programming|Programming the Clusters&lt;br /&gt;
* Other Facilities&lt;br /&gt;
** Main_Page#Visualization|Visualization&lt;br /&gt;
** Main_Page#AccessGrid|Video Conferencing&lt;br /&gt;
* Domain Specific Portals&lt;br /&gt;
** Astrophysics|Astrophysics&lt;br /&gt;
** Bioinformatics|Bioinformatics&lt;br /&gt;
** Digital_Humanities|Digital Humanities&lt;br /&gt;
** Chemistry,_Biochemistry_and_Biophysics|Chemistry, Biochemistry and Biophysics&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=File:Winscp_folders.png&amp;diff=1882</id>
		<title>File:Winscp folders.png</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=File:Winscp_folders.png&amp;diff=1882"/>
				<updated>2010-07-05T19:25:55Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: The WinSCP main interface (two drag-and-drop panes)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The WinSCP main interface (two drag-and-drop panes)&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=File:Winscp_newkey.png&amp;diff=1881</id>
		<title>File:Winscp newkey.png</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=File:Winscp_newkey.png&amp;diff=1881"/>
				<updated>2010-07-05T19:25:00Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: The WinSCP new key window&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The WinSCP new key window&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=File:Winscp_initial.png&amp;diff=1880</id>
		<title>File:Winscp initial.png</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=File:Winscp_initial.png&amp;diff=1880"/>
				<updated>2010-07-05T19:11:52Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: uploaded a new version of &amp;quot;File:Winscp initial.png&amp;quot;: Initial window re-uploaded (original had corruption)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Initial WinSCP window&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=File:Winscp_initial.png&amp;diff=1879</id>
		<title>File:Winscp initial.png</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=File:Winscp_initial.png&amp;diff=1879"/>
				<updated>2010-07-05T19:10:22Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Initial WinSCP window&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Initial WinSCP window&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=File:Putty_terminal.png&amp;diff=1877</id>
		<title>File:Putty terminal.png</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=File:Putty_terminal.png&amp;diff=1877"/>
				<updated>2010-07-05T19:05:39Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=File:Putty_newkey.png&amp;diff=1876</id>
		<title>File:Putty newkey.png</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=File:Putty_newkey.png&amp;diff=1876"/>
				<updated>2010-07-05T18:46:33Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: The PuTTY new key window&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The PuTTY new key window&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	<entry>
		<id>https://www.sharcnet.ca/help/index.php?title=File:Putty_initial.png&amp;diff=1875</id>
		<title>File:Putty initial.png</title>
		<link rel="alternate" type="text/html" href="https://www.sharcnet.ca/help/index.php?title=File:Putty_initial.png&amp;diff=1875"/>
				<updated>2010-07-05T18:35:35Z</updated>
		
		<summary type="html">&lt;p&gt;Tyson: Initial screen upon running PuTTY&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Initial screen upon running PuTTY&lt;/div&gt;</summary>
		<author><name>Tyson</name></author>	</entry>

	</feed>