gov.sandia.cognition.math.matrix.custom.NativeBlasHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cognitive-foundry Show documentation
Show all versions of cognitive-foundry Show documentation
A single jar with all the Cognitive Foundry components.
/*
* File: NativeBlasHandler.java
* Authors: Jeremy D. Wendt
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright 2015, Sandia Corporation. Under the terms of Contract
* DE-AC04-94AL85000, there is a non-exclusive license for use of this work by
* or on behalf of the U.S. Government. Export of this program may require a
* license from the United States Government. See CopyrightHistory.txt for
* complete details.
*/
package gov.sandia.cognition.math.matrix.custom;
import com.github.fommil.netlib.BLAS;
import gov.sandia.cognition.annotation.PublicationReference;
import gov.sandia.cognition.annotation.PublicationType;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
/**
* This class provides a uniform interface between working with a native-coded
* BLAS package or the jBLAS package. This code was begun from an example found
* at http://www.jeshua.me/content/code/NetlibTest.java but modified for our
* purposes.
*
* @author Jeremy D. Wendt
* @since 3.4.3
*/
@PublicationReference(author = "Jeshua",
title = "Netlib and Java",
type = PublicationType.WebPage,
year = 2013,
url = "http://www.jeshua.me/content/code/NetlibTest.java")
public class NativeBlasHandler
{
/**
* The current version of BLAS to use (a reference to javaBlas or
* nativeBlas)
*/
private Field blasCurrent;
/**
* The Java BLAS implementation. Guaranteed to exist.
*/
private Field javaBlas;
/**
* The native-code BLAS implementation. May be null if the library is not
* found.
*/
private Field nativeBlas;
/**
* Initializes the BLAS instances, searching for the native BLAS
* implementation.
*/
public NativeBlasHandler()
{
try
{
// get java blas object and make it accessible
Class> javaBlasClass = Class.forName("com.github.fommil.netlib.BLAS");
javaBlas = javaBlasClass.getDeclaredField("INSTANCE");
Field jInstance = javaBlas.getClass().getDeclaredField("modifiers");
jInstance.setAccessible(true);
jInstance.setInt(javaBlas, javaBlas.getModifiers() & ~Modifier.FINAL);
javaBlas.setAccessible(true);
blasCurrent = javaBlas;
if (nativeBlasAvailable())
{
// get native blas object and make it accessible
Class> nativeBlasClass = Class.forName(
"com.github.fommil.netlib.NativeBLAS");
nativeBlas = nativeBlasClass.getDeclaredField("INSTANCE");
Field nInstance = nativeBlas.getClass().getDeclaredField(
"modifiers");
nInstance.setAccessible(true);
nInstance.setInt(nativeBlas, nativeBlas.getModifiers()
& ~Modifier.FINAL);
nativeBlas.setAccessible(true);
blasCurrent = nativeBlas;
}
else
{
nativeBlas = null;
}
}
catch (ClassNotFoundException cnfe)
{
throw new IllegalStateException("Your machine isn't set up right",
cnfe);
}
catch (NoSuchFieldException nsfe)
{
throw new IllegalStateException("This code has errors.", nsfe);
}
catch (IllegalAccessException iae)
{
throw new IllegalStateException("This code has errors.", iae);
}
}
/**
* Returns true if BLAS is available in any form. This should always return
* true because we've included JBLAS.
*
* @return true if BLAS is available in any form.
*/
public static boolean blasAvailable()
{
return (BLAS.getInstance() != null);
}
/**
* Returns true if a native version of BLAS was found.
*
* @return true if a native version of BLAS was found
*/
public static boolean nativeBlasAvailable()
{
return (BLAS.getInstance() != null)
&& "com.github.fommil.netlib.NativeBLAS".equals(
BLAS.getInstance().getClass().getName());
}
/**
* If native BLAS is available, this sets the BLAS library to use the native
* version.
*/
final public void setToNativeBlas()
{
if (nativeBlas != null)
{
try
{
blasCurrent.set(null, nativeBlas.get(null));
}
catch (IllegalAccessException iae)
{
throw new IllegalStateException("This code has errors.", iae);
}
}
}
/**
* Sets the BLAS library to use the Java version.
*/
final public void setToJBlas()
{
try
{
blasCurrent.set(null, javaBlas.get(null));
}
catch (IllegalAccessException iae)
{
throw new IllegalStateException("This code has errors.", iae);
}
}
}