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.

Другие вопросы по тегам