jcuda cuModuleLoad() 无法使用 getClass().getResource().getPath() 的路径加载文件
jcuda cuModuleLoad() cannot load file using the path of getClass().getResource().getPath()
我正在尝试在 JCuda 中使用 cuModuleLoad()
从 /src/main/resources
加载 vectorAdd.ptx
文件。代码如下:
cuModuleLoad(module, getClass.getResource("vectorAdd.ptx").getPath())
但是 cuModuleLoad()
没有选择这个文件。它仅在我传入 ptx file
的绝对路径时有效。但我希望 ptx file
随编译 jar files
一起提供。有什么办法可以做到这一点?
cuModuleLoad
function in JCuda is a direct mapping to the corresponding cuModuleLoad
function in CUDA。它需要一个文件名作为第二个参数。
问题是:cuModuleLoad
无法加载PTX文件,因为CUDA根本不存在PTX文件! PTX 文件隐藏在 JAR 文件中。
当您使用someClass.getResource()
从JAR文件中获取资源时,它将指向JAR文件中的资源。当你做类似
的事情时
System.out.println(getClass().getResource("vectorAdd.ptx").getPath());
和 运行 这个(作为 JAR 文件),然后你会看到这样的输出:
file:/U:/YourWorkspace/YourJarFile.jar!/vectorAdd.ptx
注意 .jar!
部分:此路径 不是 真实文件的路径,而只是 JAR 中 资源的路径。
为了从 JAR 加载 PTX 文件,您必须将 PTX 文件从 JAR 读取到 Java 端的 byte[]
数组中,然后将其传递给 cuModuleLoadData
function of JCuda (which corresponds to the cuModuleLoadData
function of CUDA).
下面是一个将 PTX 数据从 JAR 文件加载到字节数组的示例,表示可以传递给 cuModuleLoadData
:
的以零结尾的字符串
import static jcuda.driver.JCudaDriver.cuCtxCreate;
import static jcuda.driver.JCudaDriver.cuDeviceGet;
import static jcuda.driver.JCudaDriver.cuInit;
import static jcuda.driver.JCudaDriver.cuModuleGetFunction;
import static jcuda.driver.JCudaDriver.cuModuleLoadData;
import static jcuda.runtime.JCuda.cudaDeviceReset;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import jcuda.driver.CUcontext;
import jcuda.driver.CUdevice;
import jcuda.driver.CUfunction;
import jcuda.driver.CUmodule;
import jcuda.driver.JCudaDriver;
public class JCudaPtxInJar
{
public static void main(String args[]) throws IOException
{
// Initialization
JCudaDriver.setExceptionsEnabled(true);
cuInit(0);
CUdevice device = new CUdevice();
cuDeviceGet(device, 0);
CUcontext context = new CUcontext();
cuCtxCreate(context, 0, device);
// Read the PTX data into a zero-terminated string byte array
byte ptxData[] = toZeroTerminatedStringByteArray(
JCudaPtxInJar.class.getResourceAsStream(
"JCudaVectorAddKernel.ptx"));
// Load the module data
CUmodule module = new CUmodule();
cuModuleLoadData(module, ptxData);
// Obtain a function pointer to the "add" function
// and print a simple test/debug message
CUfunction function = new CUfunction();
cuModuleGetFunction(function, module, "add");
System.out.println("Got function "+function);
cudaDeviceReset();
}
/**
* Read the contents of the given input stream, and return it
* as a byte array containing the ZERO-TERMINATED string data
* from the stream. The caller is responsible for closing the
* given stream.
*
* @param inputStream The input stream
* @return The ZERO-TERMINATED string byte array
* @throws IOException If an IO error occurs
*/
private static byte[] toZeroTerminatedStringByteArray(
InputStream inputStream) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buffer[] = new byte[8192];
while (true)
{
int read = inputStream.read(buffer);
if (read == -1)
{
break;
}
baos.write(buffer, 0, read);
}
baos.write(0);
return baos.toByteArray();
}
}
编译并将其打包到 JAR 中(当然连同 /resources/JCudaVectorAddKernel.ptx
PTX 文件)将允许您启动程序并从 JAR 中的 PTX 中获取示例函数。
我正在尝试在 JCuda 中使用 cuModuleLoad()
从 /src/main/resources
加载 vectorAdd.ptx
文件。代码如下:
cuModuleLoad(module, getClass.getResource("vectorAdd.ptx").getPath())
但是 cuModuleLoad()
没有选择这个文件。它仅在我传入 ptx file
的绝对路径时有效。但我希望 ptx file
随编译 jar files
一起提供。有什么办法可以做到这一点?
cuModuleLoad
function in JCuda is a direct mapping to the corresponding cuModuleLoad
function in CUDA。它需要一个文件名作为第二个参数。
问题是:cuModuleLoad
无法加载PTX文件,因为CUDA根本不存在PTX文件! PTX 文件隐藏在 JAR 文件中。
当您使用someClass.getResource()
从JAR文件中获取资源时,它将指向JAR文件中的资源。当你做类似
System.out.println(getClass().getResource("vectorAdd.ptx").getPath());
和 运行 这个(作为 JAR 文件),然后你会看到这样的输出:
file:/U:/YourWorkspace/YourJarFile.jar!/vectorAdd.ptx
注意 .jar!
部分:此路径 不是 真实文件的路径,而只是 JAR 中 资源的路径。
为了从 JAR 加载 PTX 文件,您必须将 PTX 文件从 JAR 读取到 Java 端的 byte[]
数组中,然后将其传递给 cuModuleLoadData
function of JCuda (which corresponds to the cuModuleLoadData
function of CUDA).
下面是一个将 PTX 数据从 JAR 文件加载到字节数组的示例,表示可以传递给 cuModuleLoadData
:
import static jcuda.driver.JCudaDriver.cuCtxCreate;
import static jcuda.driver.JCudaDriver.cuDeviceGet;
import static jcuda.driver.JCudaDriver.cuInit;
import static jcuda.driver.JCudaDriver.cuModuleGetFunction;
import static jcuda.driver.JCudaDriver.cuModuleLoadData;
import static jcuda.runtime.JCuda.cudaDeviceReset;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import jcuda.driver.CUcontext;
import jcuda.driver.CUdevice;
import jcuda.driver.CUfunction;
import jcuda.driver.CUmodule;
import jcuda.driver.JCudaDriver;
public class JCudaPtxInJar
{
public static void main(String args[]) throws IOException
{
// Initialization
JCudaDriver.setExceptionsEnabled(true);
cuInit(0);
CUdevice device = new CUdevice();
cuDeviceGet(device, 0);
CUcontext context = new CUcontext();
cuCtxCreate(context, 0, device);
// Read the PTX data into a zero-terminated string byte array
byte ptxData[] = toZeroTerminatedStringByteArray(
JCudaPtxInJar.class.getResourceAsStream(
"JCudaVectorAddKernel.ptx"));
// Load the module data
CUmodule module = new CUmodule();
cuModuleLoadData(module, ptxData);
// Obtain a function pointer to the "add" function
// and print a simple test/debug message
CUfunction function = new CUfunction();
cuModuleGetFunction(function, module, "add");
System.out.println("Got function "+function);
cudaDeviceReset();
}
/**
* Read the contents of the given input stream, and return it
* as a byte array containing the ZERO-TERMINATED string data
* from the stream. The caller is responsible for closing the
* given stream.
*
* @param inputStream The input stream
* @return The ZERO-TERMINATED string byte array
* @throws IOException If an IO error occurs
*/
private static byte[] toZeroTerminatedStringByteArray(
InputStream inputStream) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buffer[] = new byte[8192];
while (true)
{
int read = inputStream.read(buffer);
if (read == -1)
{
break;
}
baos.write(buffer, 0, read);
}
baos.write(0);
return baos.toByteArray();
}
}
编译并将其打包到 JAR 中(当然连同 /resources/JCudaVectorAddKernel.ptx
PTX 文件)将允许您启动程序并从 JAR 中的 PTX 中获取示例函数。