JCudpp

Java bindings for CUDPP



This library enables Java applications to use the public interface of CUDPP, the CUDA Data Parallel Primitives Library, version 2.0, which contains methods for sparse-matrix-vector-multiplications, parallel scans and sorting, as well as methods for maintaining a hash table on the device.



General information about JCudpp


JCudpp is only a Java binding for CUDPP. That means, in order to use JCudpp, you need the CUDPP library. This library can be compiled from the source code that is available at the CUDPP home page



Application



The following table shows a comparison of a sample program performing a parallel prefix scan operation using CUDPP. The left side shows the C code, which is adapted from the "Simple CUDPP" code sample at the CUDPP home page (for simplicity, error checks are omitted here). The right side shows the same operation performed with JCudpp. The workflow and the involved operations are quite similar.

(Using JCudpp for parallel prefix sums is easy! ;-) )

There also is a complete, compileable JCudpp sample on the samples page which sorts an array of integers, once in plain Java and once in JCudpp, and verifies the result.


Simple CUDPP in C Simple JCudpp in Java
// includes
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "cudpp.h"







// Program main
int mainint argc, char** argv)
{
    unsigned int numElements = 32768;
    unsigned int memSize = sizeoffloat* numElements;

    // allocate host memory
    float* h_idata = (float*mallocmemSize);

    // initialize the memory
    for (unsigned int i = 0; i < numElements; ++i)
    {
        h_idata[i(float) (rand() 0xf);
    }

    // allocate device memory
    float* d_idata;
    cudaMalloc((void**&d_idata, memSize);

    // copy host memory to device
    cudaMemcpy(d_idata, h_idata, memSize,
        cudaMemcpyHostToDevice);

    // allocate device memory for result
    float* d_odata;
    cudaMalloc((void**&d_odata, memSize);

    // Initialize the CUDPP library
    CUDPPHandle theCudpp;
    cudppCreate(&theCudpp);

    CUDPPConfiguration config;
    config.op = CUDPP_ADD;
    config.datatype = CUDPP_FLOAT;
    config.algorithm = CUDPP_SCAN;
    config.options = CUDPP_OPTION_FORWARD |
                     CUDPP_OPTION_EXCLUSIVE;

    CUDPPHandle scanplan = 0;
    cudppPlan(theCudpp, &scanplan, config, numElements, 10);

    // Run the scan
    cudppScan(scanplan, d_odata, d_idata, numElements);

    // allocate mem for the result on host side
    float* h_odata = (float*mallocmemSize);

    // copy result from device to host
    cudaMemcpy(h_odata, d_odata, memSize,
               cudaMemcpyDeviceToHost);

    cudppDestroyPlan(scanplan);
    cudppDestroy(theCudpp);
    free(h_idata);
    free(h_odata);
    cudaFree(d_idata);
    cudaFree(d_odata);
    return 0;
}
// includes
import static jcuda.runtime.JCuda.*;
import static jcuda.jcudpp.JCudpp.*;
import static jcuda.jcudpp.CUDPPOperator.*;
import static jcuda.jcudpp.CUDPPDatatype.*;
import static jcuda.jcudpp.CUDPPAlgorithm.*;
import static jcuda.jcudpp.CUDPPOption.*;
import jcuda.*;
import jcuda.runtime.*;
import jcuda.jcudpp.*;

class JCudppSample
{
    // Program main
    public static void main(String args[])
    {
        int numElements = 32768;
        int memSize = Sizeof.FLOAT * numElements;

        // allocate host memory
        float h_idata[] new float[numElements];

        // initialize the memory
        for (int i = 0; i < numElements; ++i)
        {
            h_idata[i(float)Math.random();
        }

        // allocate device memory
        Pointer d_idata = new Pointer();
        cudaMalloc(d_idata, memSize);

        // copy host memory to device
        cudaMemcpy(d_idata, Pointer.to(h_idata), memSize,
            cudaMemcpyKind.cudaMemcpyHostToDevice);

        // allocate device memory for result
        Pointer d_odata = new Pointer();
        cudaMalloc(d_odata, memSize);

        // Initialize the CUDPP library
        CUDPPHandle theCudpp = new CUDPPHandle();
        cudppCreate(theCudpp);

        CUDPPConfiguration config = new CUDPPConfiguration();
        config.op = CUDPP_ADD;
        config.datatype = CUDPP_FLOAT;
        config.algorithm = CUDPP_SCAN;
        config.options = CUDPP_OPTION_FORWARD |
                         CUDPP_OPTION_EXCLUSIVE;

        CUDPPHandle scanplan = new CUDPPHandle();
        cudppPlan(theCudpp, scanplan, config, numElements, 10);

        // Run the scan
        cudppScan(scanplan, d_odata, d_idata, numElements);

        // allocate mem for the result on host side
        float h_odata[] new float[numElements];

        // copy result from device to host
        cudaMemcpy(Pointer.to(h_odata), d_odata, memSize,
            cudaMemcpyKind.cudaMemcpyDeviceToHost);

        cudppDestroyPlan(scanplan);
        cudppDestroy(theCudpp);


        cudaFree(d_idata);
        cudaFree(d_odata);

    }
}