1. Added support for building the PairHMM vector library into build.xml.
The library is compiled using makefile and copied into the directory: build/java/classes/org/broadinstitute/sting/utils/pairhmm/ 2. Bundled the library into StingUtils.jar. Unpacked and loaded at runtime without the need to set java.library.path Caveats: Platform independence has probably been thrown out of the window. Assumptions: a. make command exists at /usr/bin/make b. rsync command exists at /usr/bin/rsync c. icc is in the PATH of the user
This commit is contained in:
parent
7815c30df8
commit
dc44b64ad8
17
build.xml
17
build.xml
|
|
@ -64,6 +64,7 @@
|
||||||
<property name="R.private.scripts.dir" value="${private.dir}/R/scripts" />
|
<property name="R.private.scripts.dir" value="${private.dir}/R/scripts" />
|
||||||
<property name="R.protected.scripts.dir" value="${protected.dir}/R/scripts" />
|
<property name="R.protected.scripts.dir" value="${protected.dir}/R/scripts" />
|
||||||
<property name="R.public.src.dir" value="${public.dir}/R/src" />
|
<property name="R.public.src.dir" value="${public.dir}/R/src" />
|
||||||
|
<property name="vector.pairhmm.library.source.dir" value="${public.dir}/c++/VectorPairHMM" />
|
||||||
|
|
||||||
<!-- Build directories -->
|
<!-- Build directories -->
|
||||||
<property name="java.classes" value="${build.dir}/java/classes" />
|
<property name="java.classes" value="${build.dir}/java/classes" />
|
||||||
|
|
@ -648,9 +649,23 @@
|
||||||
</copy>
|
</copy>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="sting-utils.jar" depends="gatk.compile, init.jar, R.public.tar, R.script.stage">
|
<target name="build.vector.pairhmm.library">
|
||||||
|
<exec dir="${vector.pairhmm.library.source.dir}" executable="/usr/bin/make">
|
||||||
|
</exec>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="copy.vector.pairhmm.library" depends="build.vector.pairhmm.library">
|
||||||
|
<exec executable="/usr/bin/rsync">
|
||||||
|
<arg value="-a"/>
|
||||||
|
<arg value="${vector.pairhmm.library.source.dir}/libVectorLoglessPairHMM.so"/>
|
||||||
|
<arg value="${java.classes}/org/broadinstitute/sting/utils/pairhmm/libVectorLoglessPairHMM.so"/>
|
||||||
|
</exec>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="sting-utils.jar" depends="gatk.compile, init.jar, R.public.tar, R.script.stage, copy.vector.pairhmm.library">
|
||||||
<jar jarfile="${dist.dir}/StingUtils.jar">
|
<jar jarfile="${dist.dir}/StingUtils.jar">
|
||||||
<fileset dir="${java.classes}" includes="**/sting/utils/**/*.class"/>
|
<fileset dir="${java.classes}" includes="**/sting/utils/**/*.class"/>
|
||||||
|
<fileset dir="${java.classes}" includes="**/sting/utils/**/*.so"/>
|
||||||
<fileset dir="${java.classes}" includes="**/sting/commandline/**/*.class"/>
|
<fileset dir="${java.classes}" includes="**/sting/commandline/**/*.class"/>
|
||||||
<fileset dir="${java.classes}" includes="**/sting/pipeline/**/*.class"/>
|
<fileset dir="${java.classes}" includes="**/sting/pipeline/**/*.class"/>
|
||||||
<fileset dir="${java.classes}" includes="**/sting/tools/**/*.class"/>
|
<fileset dir="${java.classes}" includes="**/sting/tools/**/*.class"/>
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,15 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
//For loading library from jar
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created with IntelliJ IDEA.
|
* Created with IntelliJ IDEA.
|
||||||
|
|
@ -111,7 +120,28 @@ public class VectorLoglessPairHMM extends JNILoglessPairHMM {
|
||||||
synchronized(isVectorLoglessPairHMMLibraryLoaded) {
|
synchronized(isVectorLoglessPairHMMLibraryLoaded) {
|
||||||
//Load the library and initialize the FieldIDs
|
//Load the library and initialize the FieldIDs
|
||||||
if(!isVectorLoglessPairHMMLibraryLoaded) {
|
if(!isVectorLoglessPairHMMLibraryLoaded) {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//Try loading from Java's library path first
|
||||||
|
//Useful if someone builds his/her own library and wants to override the bundled
|
||||||
|
//implementation without modifying the Java code
|
||||||
System.loadLibrary("VectorLoglessPairHMM");
|
System.loadLibrary("VectorLoglessPairHMM");
|
||||||
|
}
|
||||||
|
catch(UnsatisfiedLinkError ule)
|
||||||
|
{
|
||||||
|
//Could not load from Java's library path - try unpacking from jar
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logger.info("libVectorLoglessPairHMM not found in JVM library path - trying to unpack from StingUtils.jar");
|
||||||
|
loadLibraryFromJar("/org/broadinstitute/sting/utils/pairhmm/libVectorLoglessPairHMM.so");
|
||||||
|
}
|
||||||
|
catch(IOException ioe)
|
||||||
|
{
|
||||||
|
//Throw the UnsatisfiedLinkError to make it clear to the user what failed
|
||||||
|
throw ule;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
isVectorLoglessPairHMMLibraryLoaded = true;
|
isVectorLoglessPairHMMLibraryLoaded = true;
|
||||||
jniInitializeClassFieldsAndMachineMask(JNIReadDataHolderClass.class, JNIHaplotypeDataHolderClass.class, enableAll); //need to do this only once
|
jniInitializeClassFieldsAndMachineMask(JNIReadDataHolderClass.class, JNIHaplotypeDataHolderClass.class, enableAll); //need to do this only once
|
||||||
}
|
}
|
||||||
|
|
@ -229,4 +259,75 @@ public class VectorLoglessPairHMM extends JNILoglessPairHMM {
|
||||||
super.close();
|
super.close();
|
||||||
jniClose();
|
jniClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Copied from http://frommyplayground.com/how-to-load-native-jni-library-from-jar
|
||||||
|
/**
|
||||||
|
* Loads library from current JAR archive
|
||||||
|
*
|
||||||
|
* The file from JAR is copied into system temporary directory and then loaded. The temporary file is deleted after exiting.
|
||||||
|
* Method uses String as filename because the pathname is "abstract", not system-dependent.
|
||||||
|
*
|
||||||
|
* @param filename The filename inside JAR as absolute path (beginning with '/'), e.g. /package/File.ext
|
||||||
|
* @throws IOException If temporary file creation or read/write operation fails
|
||||||
|
* @throws IllegalArgumentException If source file (param path) does not exist
|
||||||
|
* @throws IllegalArgumentException If the path is not absolute or if the filename is shorter than three characters (restriction of {@see File#createTempFile(java.lang.String, java.lang.String)}).
|
||||||
|
*/
|
||||||
|
public static void loadLibraryFromJar(String path) throws IOException {
|
||||||
|
|
||||||
|
if (!path.startsWith("/")) {
|
||||||
|
throw new IllegalArgumentException("The path to be absolute (start with '/').");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtain filename from path
|
||||||
|
String[] parts = path.split("/");
|
||||||
|
String filename = (parts.length > 1) ? parts[parts.length - 1] : null;
|
||||||
|
|
||||||
|
// Split filename to prexif and suffix (extension)
|
||||||
|
String prefix = "";
|
||||||
|
String suffix = null;
|
||||||
|
if (filename != null) {
|
||||||
|
parts = filename.split("\\.", 2);
|
||||||
|
prefix = parts[0];
|
||||||
|
suffix = (parts.length > 1) ? "."+parts[parts.length - 1] : null; // Thanks, davs! :-)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the filename is okay
|
||||||
|
if (filename == null || prefix.length() < 3) {
|
||||||
|
throw new IllegalArgumentException("The filename has to be at least 3 characters long.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare temporary file
|
||||||
|
File temp = File.createTempFile(prefix, suffix);
|
||||||
|
//System.out.println("Temp lib file "+temp.getAbsolutePath());
|
||||||
|
temp.deleteOnExit();
|
||||||
|
|
||||||
|
if (!temp.exists()) {
|
||||||
|
throw new FileNotFoundException("File " + temp.getAbsolutePath() + " does not exist.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare buffer for data copying
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int readBytes;
|
||||||
|
|
||||||
|
// Open and check input stream
|
||||||
|
InputStream is = VectorLoglessPairHMM.class.getResourceAsStream(path);
|
||||||
|
if (is == null) {
|
||||||
|
throw new FileNotFoundException("File " + path + " was not found inside JAR.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open output stream and copy data between source file in JAR and the temporary file
|
||||||
|
OutputStream os = new FileOutputStream(temp);
|
||||||
|
try {
|
||||||
|
while ((readBytes = is.read(buffer)) != -1) {
|
||||||
|
os.write(buffer, 0, readBytes);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
// If read/write fails, close streams safely before throwing an exception
|
||||||
|
os.close();
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, load the library
|
||||||
|
System.load(temp.getAbsolutePath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue