jcuda cuModuleLoad() не может загрузить файл, используя путь getClass().getResource().getPath()
Я пытаюсь использовать cuModuleLoad()
в JCuda загрузить vectorAdd.ptx
файл из /src/main/resources
, Код выглядит следующим образом:
cuModuleLoad(module, getClass.getResource("vectorAdd.ptx").getPath())
Но cuModuleLoad()
не забирает этот файл Это работает только тогда, когда я прохожу абсолютный путь ptx file
, Но я хотел бы иметь ptx file
поставляется с компиляцией jar files
, Есть ли способ сделать это?
1 ответ
cuModuleLoad
Функция в JCuda является прямым отображением cuModuleLoad
функция в CUDA. Ожидается имя файла в качестве второго аргумента.
Проблема в: cuModuleLoad
не может загрузить файл PTX, потому что файл PTX просто не существует для CUDA! Файл PTX скрыт внутри файла JAR.
Когда вы получаете ресурс из файла JAR, используя someClass.getResource()
, затем он будет указывать на ресурс в файле JAR. Когда вы делаете что-то вроде
System.out.println(getClass().getResource("vectorAdd.ptx").getPath());
и запустите это (как файл JAR), тогда вы увидите вывод, подобный этому:
file:/U:/YourWorkspace/YourJarFile.jar!/vectorAdd.ptx
Обратите внимание .jar!
part: этот путь не путь к реальному файлу, а только путь к ресурсу в JAR.
Чтобы загрузить файл PTX из JAR, вы должны прочитать файл PTX из JAR в byte[]
массив на стороне Java, а затем передать его cuModuleLoadData
функция JCuda (которая соответствует cuModuleLoadData
функция 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) позволит вам запустить программу и получить пример функции от PTX в JAR.