2012-10-11 6 views
2

C에서 작성한 CUDA 코드가 있는데 정상적으로 작동하는 것처럼 보입니다 (일반 C 및 C++이 아님). Hadoop 클러스터를 실행하고 코드를 통합하여 이상적으로 Java 내에서 실행하려고합니다. (긴 이야기 : 시스템이 너무 복잡합니다.)Java에서 작동중인 CUDA 코드를 실행하는 가장 쉬운 방법은 무엇입니까?

현재 C 프로그램은 로그 파일을 분석 한 다음 GPU에서 각 행을 병렬로 처리 한 다음 특정 오류/트랜잭션을 연결된 목록에 저장 한 다음 드라이브에 씁니다.

이렇게하는 가장 좋은 방법은 무엇입니까? JCUDA는 C Cuda와 완벽한 매핑입니까 아니면 전혀 다른가요? 또는 Java에서 C 코드를 호출하고 결과를 공유하는 것이 좋습니다 (링크 된 목록에 액세스 할 수 있습니까)?

+1

[이 사람들을 (http://wiki.apache.org/hadoop/CUDA % 20On % 20Hadoop)는 JCuda를 사용하여 C/C++로 작성된 cuda 함수를 래핑했습니다. [루트 비어] (https://github.com/pcpratts/rootbeer1)는 또 다른 CUDA/Java 구현을 제공하지만 자바 코드로 커널 코드를 재 작성하고자한다고 가정합니다. –

답변

1

IMO? JavaCPP.

import com.googlecode.javacpp.*; 
import com.googlecode.javacpp.annotation.*; 

@Platform(include={"<thrust/host_vector.h>", "<thrust/device_vector.h>", "<thrust/generate.h>", "<thrust/sort.h>", 
        "<thrust/copy.h>", "<thrust/reduce.h>", "<thrust/functional.h>", "<algorithm>", "<cstdlib>"}) 
@Namespace("thrust") 
public class ThrustTest { 
    static { Loader.load(); } 

    public static class IntGenerator extends FunctionPointer { 
     static { Loader.load(); } 
     protected IntGenerator() { allocate(); } 
     private native void allocate(); 
     public native int call(); 
    } 

    @Name("plus<int>") 
    public static class IntPlus extends Pointer { 
     static { Loader.load(); } 
     public IntPlus() { allocate(); } 
     private native void allocate(); 
     public native @Name("operator()") int call(int x, int y); 
    } 

    @Name("host_vector<int>") 
    public static class IntHostVector extends Pointer { 
     static { Loader.load(); } 
     public IntHostVector() { allocate(0); } 
     public IntHostVector(long n) { allocate(n); } 
     public IntHostVector(IntDeviceVector v) { allocate(v); } 
     private native void allocate(long n); 
     private native void allocate(@ByRef IntDeviceVector v); 

     public IntPointer begin() { return data(); } 
     public IntPointer end() { return data().position((int)size()); } 

     public native IntPointer data(); 
     public native long size(); 
     public native void resize(long n); 
    } 

    @Name("device_ptr<int>") 
    public static class IntDevicePointer extends Pointer { 
     static { Loader.load(); } 
     public IntDevicePointer() { allocate(null); } 
     public IntDevicePointer(IntPointer ptr) { allocate(ptr); } 
     private native void allocate(IntPointer ptr); 

     public native IntPointer get(); 
    } 

    @Name("device_vector<int>") 
    public static class IntDeviceVector extends Pointer { 
     static { Loader.load(); } 
     public IntDeviceVector() { allocate(0); } 
     public IntDeviceVector(long n) { allocate(n); } 
     public IntDeviceVector(IntHostVector v) { allocate(v); } 
     private native void allocate(long n); 
     private native void allocate(@ByRef IntHostVector v); 

     public IntDevicePointer begin() { return data(); } 
     public IntDevicePointer end() { return new IntDevicePointer(data().get().position((int)size())); } 

     public native @ByVal IntDevicePointer data(); 
     public native long size(); 
     public native void resize(long n); 
    } 

    public static native @MemberGetter @Namespace IntGenerator rand(); 
    public static native void copy(@ByVal IntDevicePointer first, @ByVal IntDevicePointer last, IntPointer result); 
    public static native void generate(IntPointer first, IntPointer last, IntGenerator gen); 
    public static native void sort(@ByVal IntDevicePointer first, @ByVal IntDevicePointer last); 
    public static native int reduce(@ByVal IntDevicePointer first, @ByVal IntDevicePointer last, int init, @ByVal IntPlus binary_op); 

    public static void main(String[] args) { 
     // generate 32M random numbers serially 
     IntHostVector h_vec = new IntHostVector(32 << 20); 
     generate(h_vec.begin(), h_vec.end(), rand()); 

     // transfer data to the device 
     IntDeviceVector d_vec = new IntDeviceVector(h_vec); 

     // sort data on the device (846M keys per second on GeForce GTX 480) 
     sort(d_vec.begin(), d_vec.end()); 

     // transfer data back to host 
     copy(d_vec.begin(), d_vec.end(), h_vec.begin()); 

     // compute sum on device 
     int x = reduce(d_vec.begin(), d_vec.end(), 0, new IntPlus()); 
    } 
} 

C에 대한 여러분의 코드가 생각지도 쉽게해야한다 : 예를 들어, 다음 the main page of Thrust's Web site에 표시되는 예제의 자바 포트입니다.

우리가 할 수 얻을이, 또는 적절하게 -properties 옵션을 수정하여 지원되는 다른 플랫폼에서 컴파일이 명령 리눅스 x86_64의 실행 :

$ javac -cp javacpp.jar ThrustTest.java 
$ java -jar javacpp.jar ThrustTest -properties linux-x86_64-cuda 
$ java -cp javacpp.jar ThrustTest