2014-12-14 3 views
0

내가 Rootbeer를 사용하는 배우고,하지만 난 그 샘플 응용 프로그램을 실행했을 때 내가 붙어있어, 아무도 내 질문에 대답하지 수 : Rootbeer runtime error, how to fix?Java에서 인터페이스를 올바르게 캐스팅하는 방법은 무엇입니까?

그래서 나는 Rootbeer의 소스 코드를 다운로드하고 코드를 살펴했다

  public void setKernel(Kernel kernelTemplate) { 
      this.kernelTemplate = kernelTemplate; 
[ 119 ] this.compiledKernel = (CompiledKernel) kernelTemplate; 
      } 

그리고 커널과 CompiledKernel의 정의는 다음과 같습니다 :

public interface Kernel 
{ 
    public void gpuMethod(); 
} 

public interface CompiledKernel 
{ 
    public String getCodeUnix(); 

    public String getCodeWindows(); 

    public int getNullPointerNumber(); 

    public int getOutOfMemoryNumber(); 

    public String getCubin32(); 

    public int getCubin32Size(); 

    public boolean getCubin32Error(); 

    public String getCubin64(); 

    public int getCubin64Size(); 

    public boolean getCubin64Error(); 

    public Serializer getSerializer(Memory memory,Memory memory1); 

    public boolean isUsingGarbageCollector(); 
} 

라인 119에 제대로 캐스트가 문제가 [CUDAContext.java:119]이고, 여기? 그렇다면 다음과 같은 오류 메시지가 표시되는 이유는 무엇입니까?

java.lang.ClassCastException: ArrayMult cannot be cast to org.trifort.rootbeer.runtime.CompiledKernel 
    at org.trifort.rootbeer.runtime.CUDAContext.setKernel(CUDAContext.java:119) 

올바르게 완료되지 않은 경우 캐스팅하는 올바른 방법은 무엇입니까?

편집 : 여기

import java.util.List; 
import java.util.ArrayList; 
import org.trifort.rootbeer.runtime.Kernel; 
import org.trifort.rootbeer.runtime.Rootbeer; 

public class ArrayMultApp 
{ 
    public ArrayMultApp() 
    { 
    int[] array=new int[10]; 
    for (int i=0;i<array.length;++i) array[i]=i; 
    for (int i=0;i<array.length;++i) Out("start array["+i+"]: "+array[i]); 
    multArray(array); 
    for (int i=0;i<array.length;++i) Out("final array["+i+"]: "+array[i]); 
    } 

    public void multArray(int[] array) 
    { 
    try 
    { 
     List<Kernel> jobs=new ArrayList(); 
     for (int i=0;i<array.length;++i) jobs.add(new ArrayMult(array,i)); 
     Rootbeer rootbeer=new Rootbeer(); 
     rootbeer.run(jobs); 
    } 
    catch (Exception e) { e.printStackTrace(); } 
    } 

    public static void main(String[] args) { ArrayMultApp app=new ArrayMultApp(); } 

    private static void out(String message) { System.out.print(message); } 

    private static void Out(String message) { System.out.println(message); } 
} 

class ArrayMult implements Kernel 
{ 
    private int[] m_source; 
    private int m_index; 

    public ArrayMult(int[] source,int index) 
    { 
    m_source=source; 
    m_index=index; 
    } 

    public void gpuMethod() { m_source[m_index]*=11; } 
} 
+0

전달 된'Kernel' 객체는'CompiledKernel'도 구현하지 않습니다. 'CompiledKernel'이'Kernel'을 확장했다는 뜻입니까? –

+0

개체를 형식이 아닌 형식으로 변환 할 수 없으므로 올바른 방법이 없습니다. 사과와 같은 오렌지를 사과로 바꾸는 적절한 방법은 무엇인가 묻는 것과 조금 같습니다. –

+0

나는 컨텍스트를 올바르게 초기화하지 않았다고 생각한다. – neohope

답변

1

아니오 그렇지 않은 샘플 코드를입니다. 두 개의 서로 다른 인터페이스가 있습니다.

 public void setKernel(Kernel kernelTemplate) { 
     this.kernelTemplate = kernelTemplate; 
[ 119 ] this.compiledKernel = (CompiledKernel) kernelTemplate; 
     } 

119에서 Kernel을 각각 CompiledKernel으로 캐스팅하려고합니다. 각 커널에는 고유 한 계층 구조가 있습니다. CompiledKernel extends Kernel 인 경우이 작업이 가능합니다.

+0

아니요. 커널이 CompiledKernel을 확장하는 경우에만 작동합니다. – Daniel

+0

"Kernel extends CompiledKernel"이 컴파일되지 않습니다. 이제 "CompiledKernel extends Kernel"copmiles로 변경되었지만 여전히 동일한 런타임 오류가 발생합니다. – Frank

1

G 카드가 없으므로 코드를 테스트 할 수 없습니다. 나는 소스 코드를 살펴 봤다. 나는 또한 자신의 데모 코드를 보았다

public void run(String cls){  
    OpenCLScene scene = new OpenCLScene(); 
    OpenCLScene.setInstance(scene); 
    scene.init(); 

    SootClass soot_class1 = Scene.v().getSootClass(cls); 
    SootMethod method = soot_class1.getMethod("void gpuMethod()"); 

    String uuid = getUuid(); 
    GenerateForKernel generator = new GenerateForKernel(method, uuid); 
    try { 
    generator.makeClass(); 
    } catch(Exception ex){ 
    ex.printStackTrace(); 
    OpenCLScene.releaseV(); 
    return; 
    } 

    //add an interface to the class 
    SootClass soot_class = method.getDeclaringClass(); 
    SootClass iface_class = Scene.v().getSootClass("org.trifort.rootbeer.runtime.CompiledKernel"); 
    soot_class.addInterface(iface_class); 

    System.out.println("added interface CompiledKernel"); 

    OpenCLScene.releaseV(); 
} 

저자는 예 일종의 \ ", org.trifort.rootbeer.compiler.Transform2.java이 속임수를 썼는지 \ SRC \ 조직 \ trifort \ rootbeer의 \ 정렬 \ GPUSort.java ". 제작자가 컨텍스트를 초기화했는데, 이는 컨텍스트와 다르다. 먼저 코드를 사용해 보시기 바랍니다. 귀하의 코드가 아니라 Transform2.run 함수를 호출 내기.

public void sort(){ 
    //should have 192 threads per SM 
    int size = 2048; 
    int sizeBy2 = size/2; 
    //int numMultiProcessors = 14; 
    //int blocksPerMultiProcessor = 512; 
    int numMultiProcessors = 2; 
    int blocksPerMultiProcessor = 256; 
    int outerCount = numMultiProcessors*blocksPerMultiProcessor; 
    int[][] array = new int[outerCount][]; 
    for(int i = 0; i < outerCount; ++i){ 
    array[i] = newArray(size); 
    } 

    Rootbeer rootbeer = new Rootbeer(); 
    List<GpuDevice> devices = rootbeer.getDevices(); 
    GpuDevice device0 = devices.get(0); 
    Context context0 = device0.createContext(4212880); 
    context0.setCacheConfig(CacheConfig.PREFER_SHARED); 
    context0.setThreadConfig(sizeBy2, outerCount, outerCount * sizeBy2); 
    context0.setKernel(new GPUSortKernel(array)); 
    context0.buildState(); 
    ...... 
} 
+0

통찰력을 가져 주셔서 감사합니다. 뭔가 익숙해 져있는 것 같지만 실행 코드가 그의 예에서 나온 것입니다. 다른 사람들도이 코드와 동일한 문제가 있음을 온라인에서 발견했습니다. 작동하도록 샘플을 변경 하시겠습니까? 방금 질문에 코드를 추가했습니다. – Frank

+0

먼저이 예제를 컴파일 해보십시오. https://github.com/pcpratts/rootbeer1/tree/master/examples/sort. GPUSort.java에서 60 ~ 67 행의 코드에 주목하십시오. – neohope

+0

시도해 보니 "GPUSortKernel을 org.trifort.rootbeer.runtime.CompiledKernel"으로 캐스팅 할 수 없습니다 (줄 65) [setKernal] – Frank

0

실제 개체가 해당 인터페이스를 구현하는 경우에만 인터페이스로 캐스팅 할 수 있습니다. CUDA에 대해 많이 알지는 못하지만, 커널을 사용하고 CompiledKernel을 반환하는 메서드가있을 수 있습니다. 단순히 주조하는 것은 그렇게하지 않을 것입니다.

"ArrayMult"클래스를 만든 경우 Kernel과 CompiledKernel을 모두 구현하여이 문제를 해결할 수 있습니다.

관련 문제