zeratax / yacx

Yet Another CudaExecutor - wrapper to easily compile and execute cuda kernels
https://zeratax.github.io/yacx
MIT License
8 stars 4 forks source link

KernelArg reuse #89

Closed LukasSiefke closed 4 years ago

LukasSiefke commented 4 years ago

Es wäre gut, wenn man eigene Konstruktoren hätte um z.B. ein OutputArg bei einem weiteren Durchlauf als InputArg zu verwenden. Bisher erstellt man dafür ein neues Argument und kopiert die Daten des alten Argumentes da hinein. Dies ist aber sehr ineffizient (Es ist ein Kopieren der C-Daten in ein Java-Array und das Kopieren aus dem Java-Array in ein neues C-Array nötig). Besser wäre es, einfach ein neues Argument zu erstellen mit dem gleichen Pointer auf die Host-daten (evtl. Eingabeobjekt zerstören?)

zeratax commented 4 years ago

glaube mit #46 wäre sowas alles möglich

Edit: sorry es geht hier wohl mehr darum wie das JNI damit umgeht und nicht cuda, alles klar

Olliewer commented 4 years ago

Ich werde das mal ausprobieren, scheint ja machbar zu sein

LukasSiefke commented 4 years ago

Ja, ich habe überlegt, dass man vielleicht auch statt Konstruktoren eine "normale" Methode benutzen kann, und dann nur den Pointer auf ein neues C-Objekt ändert

Olliewer commented 4 years ago

also ich haette jetzt in IntArg z.B. in der Java Klasse eine neue Methode public static create(IntArg ints) hinzugefuegt. und die dann implementiert.

LukasSiefke commented 4 years ago

Also so ganz löst das noch nicht das Problem, dass ein Array dabei zweimal umkopiert werden muss (und der entsprechende Speicher allokiert werden muss). Ich denke am besten wäre es einfach die booleans download und copy in der C Implementierung (KernelArgs.hpp) unkonstant zu machen. Dann kann man in Java dafür native getter und setter implmentieren. Die Implementierung kann man wahrscheinlich am besten in einer neuen abstrakten Oberklasse ArrayArg machen, von der dann die anderen IntArg, etc. -Klassen erben

Wenn du Lust hättest könntest du dabei (wenn du sowieso schon so viele Header neu erzeugen musst) auch #93 anfangen (also so was wie package yacx; in jede Java-Klasse schreiben und die Methodennamen der Implementierung der native-Methoden ändern)

zeratax commented 4 years ago

so in der Richtung könnte man mit cmake der JNI header files erstellen:

ADD_CUSTOM_COMMAND(
    OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/include/MyClass_jni.h"
    COMMAND
        ${Java_JAVAH_EXECUTABLE}
        -o "${CMAKE_CURRENT_BINARY_DIR}/include/MyClass_jni.h"
        -classpath "${CMAKE_CURRENT_BINARY_DIR}/java/bin"
        edu.nyu.cpptest.cpplib.MyClass
    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/java/bin/edu/nyu/cpptest/cpplib/MyClass.class")
ADD_CUSTOM_TARGET(JavaJNIHeaders ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/include/MyClass_jni.h")

siehe https://github.com/remram44/java-cpp-example/blob/master/java-jni/CMakeLists.txt

müsste dann Wahrscheinlich einfach in die forschleife: https://github.com/ZerataX/yacx/blob/master/CMakeLists.txt#L50-L63

Edit: eig reicht es bei

add_custom_command(
      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/java/bin/${_class_file}"
      COMMAND
        ${Java_JAVAC_EXECUTABLE} ${CMAKE_JAVA_COMPILE_FLAGS} -sourcepath
        "${PROJECT_SOURCE_DIR}/src/java" -d
        "${CMAKE_CURRENT_BINARY_DIR}/java/bin"
        "${PROJECT_SOURCE_DIR}/src/java/${_java_file}"
      DEPENDS "${PROJECT_SOURCE_DIR}/src/java/${_java_file}")

einfach noch die -h flag hinzuzufügen, also

add_custom_command(
      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/java/bin/${_class_file}"
      COMMAND
        ${Java_JAVAC_EXECUTABLE} ${CMAKE_JAVA_COMPILE_FLAGS} -sourcepath
        "${PROJECT_SOURCE_DIR}/src/java" -h # etwas doppelt
        "${PROJECT_SOURCE_DIR}/src/java" -d
        "${CMAKE_CURRENT_BINARY_DIR}/java/bin"
        "${PROJECT_SOURCE_DIR}/src/java/${_java_file}"
      DEPENDS "${PROJECT_SOURCE_DIR}/src/java/${_java_file}")

und dann bei den include directories entweder src/java hinzufügen oder rausfinden wie man javac sagt wo die header files hingepackt werden sollen.

dann würde man die bei der gitignore hinzufügen und jetzt würde cmake halt selber immer die passenden header files erstellen

Olliewer commented 4 years ago

@LukasSiefke wo sind die denn const? Ich finde das nirgends, also halt nicht konstant. Ich werde dann die Dateien alle in ein Package machen. Die sind dann auch alle einfach in dem yacx Package, oder? EDIT: die Klassen IntArg und so sind doch schon Unterklassen von dem KernelArg und das ja auch schon von JNIHandle, in C koennen die ja von mehreren Klassen erben, aber in Java ja nicht. Wie kann man das loesen. Die getter und setter kann ich ja auch schlecht in KernelArg hinzufuegen @ZerataX kann ich mir danach mal angucken. mit javac file.java -h /dir finde ich es aber auch generell einfacher und schneller zu erzeugen.

LukasSiefke commented 4 years ago

Also in der Klasse KernelArg (nicht KernelArgs) (befindet sich include/yacx/KernelArgs.hpp) sind die Attribute m_copy und m_download const. Das const kann dann halt weg und dann braucht man noch so was wie getter und setter in dieser Klasse, um darauf zugreifen zu können (oder einfach public?) Du kannst IntArg von ArrayArg von KernelArg von JNIHandle ergeben lassen. Und die getter und setter dann in die neue Klasse ArrayArg als native implementieren. (die müssen dann halt die Werte von dem KernelArg-Objekt abfragen) Fürs Package muss in jede der Java-Klassen einfach nur package yacx; als erster Befehl stehen. Das nervige ist halt, dass man dann neue Header erzeugen muss und das noch nervigere ist, dass sich dann alle Methodennamen in den cpp-Datein in jni ändern

LukasSiefke commented 4 years ago

Ich habe die Java-Klasse doch mal in einen neuen Ordner verschoben, sonst ist Eclipse verwirrt und macht keine Autovervollständigung für unser Java-Zeug mehr Edit: Ich sehe gerade, dass die commit-Nachrichten falsch waren, ich meinte jeweils #93 (Verschieben der Klassen in ein neues package). An #89 habe ich nichts geändert