Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* JCuda - Java bindings for NVIDIA CUDA driver and runtime API
*
* Copyright (c) 2009-2015 Marco Hutter - http://www.jcuda.org
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
package jcuda;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Utility class for detecting the operating system and architecture
* types, and automatically loading the matching native library
* as a resource or from a file.
*
* This class is not intended to be used by clients.
*
*/
public final class LibUtils
{
// The architecture and OS detection has been adapted from
// http://javablog.co.uk/2007/05/19/making-jni-cross-platform/
// and extended with http://lopica.sourceforge.net/os.html
/**
* The logger used in this class
*/
private static final Logger logger =
Logger.getLogger(LibUtils.class.getName());
/**
* The log level
*/
private static final Level level;
// Check whether a custom level for the log messages has been defined
// as a command line parameter, as in
// java -Djcuda.LibUtils.level=INFO ...
static
{
String levelPropertyName = "jcuda.LibUtils.level";
String levelValue = System.getProperty(levelPropertyName);
Level parsedLevel = Level.FINE;
if (levelValue != null)
{
try
{
parsedLevel = Level.parse(levelValue);
}
catch (IllegalArgumentException e)
{
logger.warning("Invalid value for " + levelPropertyName
+ ": " + levelValue + " - defaulting to Level.FINE");
}
}
level = parsedLevel;
}
/**
* The directory where libraries are expected in JAR files,
* when they are loaded as resources
*/
private static final String LIBRARY_PATH_IN_JAR = "/lib";
/**
* Enumeration of common operating systems, independent of version
* or architecture.
*/
public static enum OSType
{
ANDROID, APPLE, LINUX, SUN, WINDOWS, UNKNOWN
}
/**
* Enumeration of common CPU architectures.
*/
public static enum ArchType
{
PPC, PPC_64, SPARC, X86, X86_64, ARM, ARM64, AARCH64, MIPS, MIPS64,
RISC, UNKNOWN
}
/**
* Private constructor to prevent instantiation.
*/
private LibUtils()
{
// Private constructor to prevent instantiation.
}
/**
* Loads the specified library.
*
* The method will attempt to load the library using the usual
* System.loadLibrary call. In this case, the specified
* dependent libraries are ignored, because they are assumed to be
* loaded automatically in the same way as the main library.
*
* If the library can not be loaded with the
* System.loadLibrary call, then this method will attempt
* to load the file as a resource (usually one that is contained in
* a JAR file). In this case, the library is assumed to be located
* in subdirectory called "/lib" inside the JAR file.
* The method will try to load a resource that has the platform-specific
* {@link #createLibraryFileName(String) library file name} from
* this directory, extract it into the default directory for temporary
* files, and load the library from there.
*
* In this case, the specified dependent libraries may also be loaded
* as resources. They are assumed to be located in subdirectories
* that are named according to the {@link #osString()} and
* {@link #archString()} of the executing platform. For example, such
* a library may be located in a directory inside the JAR that is
* called "/lib/windows/x86_64". These dependent libraries
* will be extracted and loaded before the main library is loaded.
*
* @param libraryName The name of the library (without a platform specific
* prefix or file extension)
* @param dependentLibraryNames The names of libraries that the library
* to load depends on. If the library is loaded as a resource, then
* it will be attempted to also load these libraries as resources, as
* described above
* @throws UnsatisfiedLinkError if the native library
* could not be loaded.
*/
public static void loadLibrary(
String libraryName, String ... dependentLibraryNames)
{
logger.log(level, "Loading library: " + libraryName);
// First, try to load the specified library as a file
// that is visible in the default search path
Throwable throwableFromFile;
try
{
logger.log(level, "Loading library as a file");
System.loadLibrary(libraryName);
logger.log(level, "Loading library as a file DONE");
return;
}
catch (Throwable t)
{
logger.log(level, "Loading library as a file FAILED");
throwableFromFile = t;
}
// Now try to load the library by extracting the
// corresponding resource from the JAR file
try
{
logger.log(level, "Loading library as a resource");
loadLibraryResource(LIBRARY_PATH_IN_JAR,
libraryName, "", dependentLibraryNames);
logger.log(level, "Loading library as a resource DONE");
return;
}
catch (Throwable throwableFromResource)
{
logger.log(level, "Loading library as a resource FAILED",
throwableFromResource);
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
pw.println("Error while loading native library \"" +
libraryName + "\"");
pw.println("Operating system name: "+
System.getProperty("os.name"));
pw.println("Architecture : "+
System.getProperty("os.arch"));
pw.println("Architecture bit size: "+
System.getProperty("sun.arch.data.model"));
pw.println("---(start of nested stack traces)---");
pw.println("Stack trace from the attempt to " +
"load the library as a file:");
throwableFromFile.printStackTrace(pw);
pw.println("Stack trace from the attempt to " +
"load the library as a resource:");
throwableFromResource.printStackTrace(pw);
pw.println("---(end of nested stack traces)---");
pw.close();
throw new UnsatisfiedLinkError(sw.toString());
}
}
/**
* Load the library with the given name from a resource.
*
* @param resourceSubdirectoryName The subdirectory where the resource
* is expected
* @param libraryName The library name, e.g. "EXAMPLE-windows-x86"
* @param tempSubdirectoryName The name for the subdirectory in the
* temp directory, where the temporary files for dependent libraries
* should be stored
* @param dependentLibraryNames The names of libraries that the library
* to load depends on, and that may have to be loaded as resources and
* stored as temporary files as well
* @throws Throwable If the library could not be loaded
*/
private static void loadLibraryResource(
String resourceSubdirectoryName,
String libraryName,
String tempSubdirectoryName,
String ... dependentLibraryNames) throws Throwable
{
// First try to load all dependent libraries, recursively
for (String dependentLibraryName : dependentLibraryNames)
{
logger.log(level,
"Library " + libraryName +
" depends on " + dependentLibraryName);
String dependentResourceSubdirectoryName =
resourceSubdirectoryName + "/" +
osString() + "/" +
archString();
String dependentLibraryTempSubDirectoryName =
libraryName + "_dependents" + File.separator +
osString() + File.separator +
archString() + File.separator;
loadLibraryResource(
dependentResourceSubdirectoryName,
dependentLibraryName,
dependentLibraryTempSubDirectoryName);
}
// Now, prepare loading the actual library
String libraryFileName = createLibraryFileName(libraryName);
File libraryTempFile = createTempFile(
tempSubdirectoryName, libraryFileName);
// If the temporary file for the library does not exist, create it
if (!libraryTempFile.exists())
{
String libraryResourceName =
resourceSubdirectoryName + "/" + libraryFileName;
logger.log(level,
"Writing resource " + libraryResourceName);
logger.log(level,
"to temporary file " + libraryTempFile);
writeResourceToFile(libraryResourceName, libraryTempFile);
}
// Finally, try to load the library from the temporary file
logger.log(level, "Loading library " + libraryTempFile);
System.load(libraryTempFile.toString());
logger.log(level, "Loading library " + libraryTempFile + " DONE");
}
/**
* Create a file object representing the file with the given name
* in the specified subdirectory of the default "temp" directory.
* If the specified subdirectory does not exist yet, it is created.
*
* @param name The file name
* @return The file
* @throws IOException If the subdirectory can not be created
*/
private static File createTempFile(
String tempSubdirectoryName, String name) throws IOException
{
String tempDirName = System.getProperty("java.io.tmpdir");
File tempSubDirectory =
new File(tempDirName + File.separator + tempSubdirectoryName);
if (!tempSubDirectory.exists())
{
boolean createdDirectory = tempSubDirectory.mkdirs();
if (!createdDirectory)
{
throw new IOException(
"Could not create directory for temporary file: " +
tempSubDirectory);
}
}
String tempFileName = tempSubDirectory + File.separator + name;
File tempFile = new File(tempFileName);
return tempFile;
}
/**
* Obtain an input stream to the resource with the given name, and write
* it to the specified file (which may not be null, and
* may not exist yet)
*
* @param resourceName The name of the resource
* @param file The file to write to
* @throws NullPointerException If the given file is null
* @throws IllegalArgumentException If the given file already exists
* @throws IOException If an IO error occurs
*/
private static void writeResourceToFile(
String resourceName, File file) throws IOException
{
if (file == null)
{
throw new NullPointerException("Target file may not be null");
}
if (file.exists())
{
throw new IllegalArgumentException(
"Target file already exists: "+file);
}
InputStream inputStream =
LibUtils.class.getResourceAsStream(resourceName);
if (inputStream == null)
{
throw new IOException(
"No resource found with name '"+resourceName+"'");
}
OutputStream outputStream = null;
try
{
outputStream = new FileOutputStream(file);
byte[] buffer = new byte[32768];
while (true)
{
int read = inputStream.read(buffer);
if (read < 0)
{
break;
}
outputStream.write(buffer, 0, read);
}
outputStream.flush();
}
finally
{
if (outputStream != null)
{
try
{
outputStream.close();
}
catch (IOException e)
{
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
try
{
inputStream.close();
}
catch (IOException e)
{
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
}
/**
/**
* Create the full library file name, including the extension
* and prefix, for the given library name. For example, the
* name "EXAMPLE" will become
* EXAMPLE.dll on Windows
* libEXAMPLE.so on Linux
* EXAMPLE.dylib on MacOS
*
* @param libraryName The library name
* @return The full library name, with extension
*/
public static String createLibraryFileName(String libraryName)
{
String libPrefix = createLibraryPrefix();
String libExtension = createLibraryExtension();
String fullName = libPrefix + libraryName + "." + libExtension;
return fullName;
}
/**
* Returns the extension for dynamically linked libraries on the
* current OS. That is, returns "dylib" on Apple,
* "so" on Linux and Sun, and "dll"
* on Windows.
*
* @return The library extension
*/
private static String createLibraryExtension()
{
OSType osType = calculateOS();
switch (osType)
{
case APPLE:
return "dylib";
case ANDROID:
case LINUX:
case SUN:
return "so";
case WINDOWS:
return "dll";
default:
break;
}
return "";
}
/**
* Returns the prefix for dynamically linked libraries on the
* current OS. That is, returns "lib" on Apple,
* Linux and Sun, and the empty String on Windows.
*
* @return The library prefix
*/
private static String createLibraryPrefix()
{
OSType osType = calculateOS();
switch (osType)
{
case ANDROID:
case APPLE:
case LINUX:
case SUN:
return "lib";
case WINDOWS:
return "";
default:
break;
}
return "";
}
/**
* Creates the name for the native library with the given base name for
* the current platform, by appending strings that indicate the current
* operating system and architecture.
*
* The resulting name will be of the form
* baseName-OSType-ArchType
* where OSType and ArchType are the lower case Strings
* of the respective {@link LibUtils.OSType OSType} and
* {@link LibUtils.ArchType ArcType} enum constants.
*
* For example, the library name with the base name "EXAMPLE" may be
* EXAMPLE-windows-x86
*
* Note that the resulting name will not include any platform specific
* prefixes or extensions for the actual name.
*
* @param baseName The base name of the library
* @return The library name
*/
public static String createPlatformLibraryName(String baseName)
{
return baseName + "-" + osString() + "-" + archString();
}
/**
* Returns a the lower case String representation of
* the {@link #calculateOS() OSType} of this platform. E.g.
* "windows".
*
* @return The string describing the operating system
*/
private static String osString()
{
OSType osType = calculateOS();
return osType.toString().toLowerCase(Locale.ENGLISH);
}
/**
* Returns a the lower case String representation of
* the {@link #calculateArch() ArchType} of this platform. E.g.
* "x86_64".
*
* @return The string describing the architecture
*/
private static String archString()
{
ArchType archType = calculateArch();
return archType.toString().toLowerCase(Locale.ENGLISH);
}
/**
* Calculates the current OSType
*
* @return The current OSType
*/
public static OSType calculateOS()
{
String vendor = System.getProperty("java.vendor");
if ("The Android Project".equals(vendor))
{
return OSType.ANDROID;
}
String osName = System.getProperty("os.name");
osName = osName.toLowerCase(Locale.ENGLISH);
if (osName.startsWith("mac os"))
{
return OSType.APPLE;
}
if (osName.startsWith("windows"))
{
return OSType.WINDOWS;
}
if (osName.startsWith("linux"))
{
return OSType.LINUX;
}
if (osName.startsWith("sun"))
{
return OSType.SUN;
}
return OSType.UNKNOWN;
}
/**
* Calculates the current ARCHType
*
* @return The current ARCHType
*/
public static ArchType calculateArch()
{
String osArch = System.getProperty("os.arch");
osArch = osArch.toLowerCase(Locale.ENGLISH);
if ("i386".equals(osArch) ||
"x86".equals(osArch) ||
"i686".equals(osArch))
{
return ArchType.X86;
}
if (osArch.startsWith("amd64") || osArch.startsWith("x86_64"))
{
return ArchType.X86_64;
}
if (osArch.startsWith("arm64"))
{
return ArchType.ARM64;
}
if (osArch.startsWith("arm"))
{
return ArchType.ARM;
}
if ("ppc".equals(osArch) || "powerpc".equals(osArch))
{
return ArchType.PPC;
}
if (osArch.startsWith("ppc"))
{
return ArchType.PPC_64;
}
if (osArch.startsWith("sparc"))
{
return ArchType.SPARC;
}
if (osArch.startsWith("mips64"))
{
return ArchType.MIPS64;
}
if (osArch.startsWith("mips"))
{
return ArchType.MIPS;
}
if (osArch.contains("risc"))
{
return ArchType.RISC;
}
if (osArch.startsWith("aarch64"))
{
return ArchType.AARCH64;
}
return ArchType.UNKNOWN;
}
}