Skip to content

Commit 983e073

Browse files
authored
Enable IntelInflater (#1885)
* Fix longstanding bug so we use the Intel Inflater when it is requested * We have been using the Java Inflater even when the Intel one was available and requested due to a bug in the configuration of the default inflater. The fix is fairly brittle because it depends on the order of initialization of various things. * This will be fixed more generally by samtools/htsjdk#1666 * Add a test
1 parent e67fe94 commit 983e073

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

src/main/java/picard/cmdline/CommandLineProgram.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,6 @@ public int instanceMain(final String[] argv) {
218218
this.defaultHeaders.add(new StringHeader("Started on: " + startDate));
219219

220220
Log.setGlobalLogLevel(VERBOSITY);
221-
SamReaderFactory.setDefaultValidationStringency(VALIDATION_STRINGENCY);
222221

223222
// Set the compression level everywhere we can think of
224223
BlockCompressedOutputStream.setDefaultCompressionLevel(COMPRESSION_LEVEL);
@@ -257,6 +256,10 @@ public int instanceMain(final String[] argv) {
257256
BlockGunzipper.setDefaultInflaterFactory(new IntelInflaterFactory());
258257
}
259258

259+
// This has to happen after the inflater factory is set because it causes a reinitialization of the static
260+
// default reader factory. At least until https://github.com/samtools/htsjdk/issues/1666 is resolved
261+
SamReaderFactory.setDefaultValidationStringency(VALIDATION_STRINGENCY);
262+
260263
if (!QUIET) {
261264
System.err.println("[" + new Date() + "] " + commandLine);
262265

src/test/java/picard/IntelInflaterDeflaterLoadTest.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
package picard;
22

33
import com.intel.gkl.compression.IntelDeflater;
4+
import com.intel.gkl.compression.IntelDeflaterFactory;
45
import com.intel.gkl.compression.IntelInflater;
6+
import com.intel.gkl.compression.IntelInflaterFactory;
7+
import htsjdk.samtools.SAMFileWriterFactory;
8+
import htsjdk.samtools.SamReaderFactory;
9+
import htsjdk.samtools.util.zip.DeflaterFactory;
10+
import htsjdk.samtools.util.zip.InflaterFactory;
511
import org.apache.commons.lang3.SystemUtils;
12+
import org.broadinstitute.barclay.argparser.CommandLineProgramProperties;
613
import org.testng.Assert;
714
import org.testng.SkipException;
815
import org.testng.annotations.Test;
16+
import picard.cmdline.CommandLineProgram;
17+
import picard.cmdline.programgroups.OtherProgramGroup;
18+
import picard.cmdline.programgroups.Testing;
19+
20+
import java.lang.reflect.Field;
921

1022
/**
1123
* Test that the Intel Inflater and Deflater can be loaded successfully.
@@ -25,6 +37,20 @@ public void testIntelDeflaterIsAvailable() {
2537
"Intel shared library was not loaded. This could be due to a configuration error, or your system might not support it.");
2638
}
2739

40+
@Test
41+
public void testIntelInflaterIsUsed(){
42+
final InflaterDeflaterTester cmd = new InflaterDeflaterTester();
43+
cmd.instanceMain(new String[]{});
44+
Assert.assertEquals(cmd.inflaterFactory.getClass(), IntelInflaterFactory.class);
45+
}
46+
47+
@Test
48+
public void testDeflaterIsUsed(){
49+
final InflaterDeflaterTester cmd = new InflaterDeflaterTester();
50+
cmd.instanceMain(new String[]{});
51+
Assert.assertEquals(cmd.deflaterFactory.getClass(), IntelDeflaterFactory.class);
52+
}
53+
2854
private void checkIntelSupported(final String componentName) {
2955
if (!SystemUtils.IS_OS_LINUX && !SystemUtils.IS_OS_MAC) {
3056
throw new SkipException(componentName + " is not available on this platform");
@@ -34,4 +60,35 @@ private void checkIntelSupported(final String componentName) {
3460
throw new SkipException(componentName + " is not available for this architecture");
3561
}
3662
}
63+
64+
65+
@CommandLineProgramProperties(summary = "test program for checking if the intel optimized inflater/deflater are active",
66+
oneLineSummary = "test program please ignore",
67+
programGroup = Testing.class,
68+
omitFromCommandLine = true)
69+
public static class InflaterDeflaterTester extends CommandLineProgram {
70+
public InflaterFactory inflaterFactory;
71+
public DeflaterFactory deflaterFactory;
72+
73+
@Override
74+
protected int doWork() {
75+
final SamReaderFactory samReaderFactory = SamReaderFactory.makeDefault();
76+
inflaterFactory = getFieldValue(samReaderFactory, "inflaterFactory", InflaterFactory.class);
77+
78+
final SAMFileWriterFactory samFileWriterFactory = new SAMFileWriterFactory();
79+
deflaterFactory = getFieldValue(samFileWriterFactory, "deflaterFactory", DeflaterFactory.class);
80+
81+
return 0;
82+
}
83+
84+
private <T,R> R getFieldValue(final T obj,final String fieldName, Class<R> clazz) {
85+
try {
86+
final Field deflaterFactoryField = obj.getClass().getDeclaredField(fieldName);
87+
deflaterFactoryField.setAccessible(true);
88+
return clazz.cast(deflaterFactoryField.get(obj));
89+
} catch (NoSuchFieldException | IllegalAccessException e) {
90+
throw new RuntimeException(e);
91+
}
92+
}
93+
}
3794
}

0 commit comments

Comments
 (0)