From 3d59d85ec88697ec4fa82f108260431f94db0aaa Mon Sep 17 00:00:00 2001 From: Lukas Date: Tue, 18 Feb 2020 15:16:41 +0100 Subject: [PATCH 1/4] build.sbt --- CMakeLists.txt | 57 ++++++++++--------- build.sbt | 23 ++++++++ include/yacx/cexecutor/CProgram.hpp | 2 +- include/yacx/cexecutor/LibaryLoader.hpp | 9 ++- src/cexecutor/CProgram.cpp | 15 +++-- src/jni/yacx_CProgram.cpp | 2 +- src/{ => main}/java/yacx/ArrayArg.java | 0 src/{ => main}/java/yacx/BooleanArg.java | 0 src/{ => main}/java/yacx/ByteArg.java | 0 src/{ => main}/java/yacx/CProgram.java | 0 src/{ => main}/java/yacx/Device.java | 0 src/{ => main}/java/yacx/DoubleArg.java | 0 src/{ => main}/java/yacx/Executor.java | 0 .../java/yacx/ExecutorFailureException.java | 0 src/{ => main}/java/yacx/FloatArg.java | 0 src/{ => main}/java/yacx/HalfArg.java | 0 src/{ => main}/java/yacx/Headers.java | 0 src/{ => main}/java/yacx/IntArg.java | 0 src/{ => main}/java/yacx/JNIHandle.java | 0 src/{ => main}/java/yacx/Kernel.java | 0 src/{ => main}/java/yacx/KernelArg.java | 0 src/{ => main}/java/yacx/KernelTime.java | 0 src/{ => main}/java/yacx/LongArg.java | 0 src/{ => main}/java/yacx/Options.java | 0 src/{ => main}/java/yacx/PaddingArg.java | 0 src/{ => main}/java/yacx/Program.java | 0 src/{ => main}/java/yacx/ShortArg.java | 0 src/{ => main}/java/yacx/Utils.java | 0 yacx.sh | 18 +++--- 29 files changed, 80 insertions(+), 46 deletions(-) create mode 100644 build.sbt rename src/{ => main}/java/yacx/ArrayArg.java (100%) rename src/{ => main}/java/yacx/BooleanArg.java (100%) rename src/{ => main}/java/yacx/ByteArg.java (100%) rename src/{ => main}/java/yacx/CProgram.java (100%) rename src/{ => main}/java/yacx/Device.java (100%) rename src/{ => main}/java/yacx/DoubleArg.java (100%) rename src/{ => main}/java/yacx/Executor.java (100%) rename src/{ => main}/java/yacx/ExecutorFailureException.java (100%) rename src/{ => main}/java/yacx/FloatArg.java (100%) rename src/{ => main}/java/yacx/HalfArg.java (100%) rename src/{ => main}/java/yacx/Headers.java (100%) rename src/{ => main}/java/yacx/IntArg.java (100%) rename src/{ => main}/java/yacx/JNIHandle.java (100%) rename src/{ => main}/java/yacx/Kernel.java (100%) rename src/{ => main}/java/yacx/KernelArg.java (100%) rename src/{ => main}/java/yacx/KernelTime.java (100%) rename src/{ => main}/java/yacx/LongArg.java (100%) rename src/{ => main}/java/yacx/Options.java (100%) rename src/{ => main}/java/yacx/PaddingArg.java (100%) rename src/{ => main}/java/yacx/Program.java (100%) rename src/{ => main}/java/yacx/ShortArg.java (100%) rename src/{ => main}/java/yacx/Utils.java (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 04f97ea..50f4461 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,35 +12,38 @@ add_definitions(-DNVRTC_GET_TYPE_NAME=1) include_directories(include) include_directories(include/yacx) -include_directories(include/yacx/cexecutor) +include_directories(${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}) + +link_directories("${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}/../lib") + +link_libraries(cuda nvrtc) -link_libraries(cuda nvrtc dl) file(GLOB SOURCES "src/*.cpp" "src/cexecutor/*.cpp") file(GLOB JNI_SOURCE_FILES "src/jni/*.cpp") set(JAVA_SOURCE_FILES - "src/java/yacx/ArrayArg.java" - "src/java/yacx/BooleanArg.java" - "src/java/yacx/ByteArg.java" - "src/java/yacx/CProgram.java" - "src/java/yacx/Device.java" - "src/java/yacx/DoubleArg.java" - "src/java/yacx/Executor.java" - "src/java/yacx/ExecutorFailureException.java" - "src/java/yacx/FloatArg.java" - "src/java/yacx/HalfArg.java" - "src/java/yacx/Headers.java" - "src/java/yacx/IntArg.java" - "src/java/yacx/JNIHandle.java" - "src/java/yacx/Kernel.java" - "src/java/yacx/KernelArg.java" - "src/java/yacx/KernelTime.java" - "src/java/yacx/LongArg.java" - "src/java/yacx/Options.java" - "src/java/yacx/PaddingArg.java" - "src/java/yacx/Program.java" - "src/java/yacx/ShortArg.java" - "src/java/yacx/Utils.java") + "src/main/java/yacx/ArrayArg.java" + "src/main/java/yacx/BooleanArg.java" + "src/main/java/yacx/ByteArg.java" + "src/main/java/yacx/CProgram.java" + "src/main/java/yacx/Device.java" + "src/main/java/yacx/DoubleArg.java" + "src/main/java/yacx/Executor.java" + "src/main/java/yacx/ExecutorFailureException.java" + "src/main/java/yacx/FloatArg.java" + "src/main/java/yacx/HalfArg.java" + "src/main/java/yacx/Headers.java" + "src/main/java/yacx/IntArg.java" + "src/main/java/yacx/JNIHandle.java" + "src/main/java/yacx/Kernel.java" + "src/main/java/yacx/KernelArg.java" + "src/main/java/yacx/KernelTime.java" + "src/main/java/yacx/LongArg.java" + "src/main/java/yacx/Options.java" + "src/main/java/yacx/PaddingArg.java" + "src/main/java/yacx/Program.java" + "src/main/java/yacx/ShortArg.java" + "src/main/java/yacx/Utils.java") add_library(yacx SHARED ${SOURCES}) @@ -61,10 +64,10 @@ if(JNI_ENABLED) OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/java/bin/yacx/${_class_file}" COMMAND ${Java_JAVAC_EXECUTABLE} ${CMAKE_JAVA_COMPILE_FLAGS} -sourcepath - "${PROJECT_SOURCE_DIR}/src/java/" -d + "${PROJECT_SOURCE_DIR}/src/main/java/" -d "${CMAKE_CURRENT_BINARY_DIR}/java/bin" - "${PROJECT_SOURCE_DIR}/src/java/yacx/${_java_file}" - DEPENDS "${PROJECT_SOURCE_DIR}/src/java/yacx/${_java_file}") + "${PROJECT_SOURCE_DIR}/src/main/java/yacx/${_java_file}" + DEPENDS "${PROJECT_SOURCE_DIR}/src/main/java/yacx/${_java_file}") list(APPEND class_files "java/bin/yacx/${_class_file}") endforeach() add_custom_target(JNIClasses ALL DEPENDS ${class_files}) diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..799775f --- /dev/null +++ b/build.sbt @@ -0,0 +1,23 @@ + +ThisBuild / scalaVersion := "2.12.10" + +lazy val buildExecutor = taskKey[Unit]("Builds C executor library") + +buildExecutor := { + import scala.language.postfixOps + import scala.sys.process._ + //noinspection PostfixMethodCall + "echo y" #| (baseDirectory.value + "/yacx.sh --buildj") ! +} + +lazy val CUexecutor = (project in file(".")) + .settings( + name := "CUDA executor", + version := "0.4.1", + libraryDependencies += "junit" % "junit" % "4.11", + + compileOrder := CompileOrder.JavaThenScala, + + compile := ((compile in Compile) dependsOn buildExecutor).value, + test := ((test in Test) dependsOn buildExecutor).value +) diff --git a/include/yacx/cexecutor/CProgram.hpp b/include/yacx/cexecutor/CProgram.hpp index 0f57d30..a4be489 100644 --- a/include/yacx/cexecutor/CProgram.hpp +++ b/include/yacx/cexecutor/CProgram.hpp @@ -11,7 +11,7 @@ class CProgram : public JNIHandle { const char *compilerWithOptions); ~CProgram(); - void execute(void **arguments); + void execute(void **arguments, bool* pointerArg); int getNumberArguments() const { return m_numberArguments; } private: diff --git a/include/yacx/cexecutor/LibaryLoader.hpp b/include/yacx/cexecutor/LibaryLoader.hpp index b62cf42..dbbcc02 100644 --- a/include/yacx/cexecutor/LibaryLoader.hpp +++ b/include/yacx/cexecutor/LibaryLoader.hpp @@ -3,15 +3,20 @@ namespace yacx { namespace detail { struct dynop { - void (*op)(void **parameter); + void (*op)(void **parameter, bool* pointerArg); void *libhandle; }; struct opfn { - void (*op)(void **parameter); + void (*op)(void **parameter, bool* pointerArg); }; +//! loads a libary and search a specific operation +//! \param dest struct to store information +//! \param filename name of the libary void load_op(struct dynop *dest, const char *filename); +//! unloads the libary and cleans the struct +//! \param op void unload_op(struct dynop *op); } // namespace detail } // namespace yacx \ No newline at end of file diff --git a/src/cexecutor/CProgram.cpp b/src/cexecutor/CProgram.cpp index 12d1b65..0b4365b 100644 --- a/src/cexecutor/CProgram.cpp +++ b/src/cexecutor/CProgram.cpp @@ -58,14 +58,17 @@ void CProgram::createSrcFile(const char* cProgram, const char* functionName, int //function for start function to be executed fileOut << "void " << executeFunctionName << " ("; - fileOut << "void** parameter"; + fileOut << "void** parameter, bool* pointerArg"; fileOut << ") {\n"; //run function to be executed fileOut << " " << functionName << "("; - for (int i = 0; i < numberParameters-1; i++){ - fileOut << "parameter[" << i << "], "; + int i = 0; + for (; i < numberParameters-1; i++){ + fileOut << "\n "; + fileOut << "pointerArg[" << i << "] ? parameter[" << i << "] : *((char*) parameter[" << i <<"]),"; } - fileOut << "parameter[" << numberParameters-1 << "]"; + fileOut << "\n "; + fileOut << "pointerArg[" << i << "] ? parameter[" << i << "] : *((char*) parameter[" << i <<"])"; fileOut << ");\n"; fileOut << "}\n\n"; @@ -106,7 +109,7 @@ void CProgram::compile(const char* cProgram, const char* functionName, int numbe } } -void CProgram::execute(void** arguments) { +void CProgram::execute(void** arguments, bool* pointerArg) { logger(loglevel::DEBUG) << "execute CProgram: " << m_srcFile; - m_op.op(arguments); + m_op.op(arguments, pointerArg); } \ No newline at end of file diff --git a/src/jni/yacx_CProgram.cpp b/src/jni/yacx_CProgram.cpp index ccc0530..0bba09d 100644 --- a/src/jni/yacx_CProgram.cpp +++ b/src/jni/yacx_CProgram.cpp @@ -65,6 +65,6 @@ void Java_yacx_CProgram_execute(JNIEnv* env, jobject obj, jobjectArray jKernelAr argsPtr[i] = kernelArgJNIPtr->getHostData(); } - cProgramPtr->execute(argsPtr); + //cProgramPtr->execute(argsPtr); END_TRY("executing cProgram") } diff --git a/src/java/yacx/ArrayArg.java b/src/main/java/yacx/ArrayArg.java similarity index 100% rename from src/java/yacx/ArrayArg.java rename to src/main/java/yacx/ArrayArg.java diff --git a/src/java/yacx/BooleanArg.java b/src/main/java/yacx/BooleanArg.java similarity index 100% rename from src/java/yacx/BooleanArg.java rename to src/main/java/yacx/BooleanArg.java diff --git a/src/java/yacx/ByteArg.java b/src/main/java/yacx/ByteArg.java similarity index 100% rename from src/java/yacx/ByteArg.java rename to src/main/java/yacx/ByteArg.java diff --git a/src/java/yacx/CProgram.java b/src/main/java/yacx/CProgram.java similarity index 100% rename from src/java/yacx/CProgram.java rename to src/main/java/yacx/CProgram.java diff --git a/src/java/yacx/Device.java b/src/main/java/yacx/Device.java similarity index 100% rename from src/java/yacx/Device.java rename to src/main/java/yacx/Device.java diff --git a/src/java/yacx/DoubleArg.java b/src/main/java/yacx/DoubleArg.java similarity index 100% rename from src/java/yacx/DoubleArg.java rename to src/main/java/yacx/DoubleArg.java diff --git a/src/java/yacx/Executor.java b/src/main/java/yacx/Executor.java similarity index 100% rename from src/java/yacx/Executor.java rename to src/main/java/yacx/Executor.java diff --git a/src/java/yacx/ExecutorFailureException.java b/src/main/java/yacx/ExecutorFailureException.java similarity index 100% rename from src/java/yacx/ExecutorFailureException.java rename to src/main/java/yacx/ExecutorFailureException.java diff --git a/src/java/yacx/FloatArg.java b/src/main/java/yacx/FloatArg.java similarity index 100% rename from src/java/yacx/FloatArg.java rename to src/main/java/yacx/FloatArg.java diff --git a/src/java/yacx/HalfArg.java b/src/main/java/yacx/HalfArg.java similarity index 100% rename from src/java/yacx/HalfArg.java rename to src/main/java/yacx/HalfArg.java diff --git a/src/java/yacx/Headers.java b/src/main/java/yacx/Headers.java similarity index 100% rename from src/java/yacx/Headers.java rename to src/main/java/yacx/Headers.java diff --git a/src/java/yacx/IntArg.java b/src/main/java/yacx/IntArg.java similarity index 100% rename from src/java/yacx/IntArg.java rename to src/main/java/yacx/IntArg.java diff --git a/src/java/yacx/JNIHandle.java b/src/main/java/yacx/JNIHandle.java similarity index 100% rename from src/java/yacx/JNIHandle.java rename to src/main/java/yacx/JNIHandle.java diff --git a/src/java/yacx/Kernel.java b/src/main/java/yacx/Kernel.java similarity index 100% rename from src/java/yacx/Kernel.java rename to src/main/java/yacx/Kernel.java diff --git a/src/java/yacx/KernelArg.java b/src/main/java/yacx/KernelArg.java similarity index 100% rename from src/java/yacx/KernelArg.java rename to src/main/java/yacx/KernelArg.java diff --git a/src/java/yacx/KernelTime.java b/src/main/java/yacx/KernelTime.java similarity index 100% rename from src/java/yacx/KernelTime.java rename to src/main/java/yacx/KernelTime.java diff --git a/src/java/yacx/LongArg.java b/src/main/java/yacx/LongArg.java similarity index 100% rename from src/java/yacx/LongArg.java rename to src/main/java/yacx/LongArg.java diff --git a/src/java/yacx/Options.java b/src/main/java/yacx/Options.java similarity index 100% rename from src/java/yacx/Options.java rename to src/main/java/yacx/Options.java diff --git a/src/java/yacx/PaddingArg.java b/src/main/java/yacx/PaddingArg.java similarity index 100% rename from src/java/yacx/PaddingArg.java rename to src/main/java/yacx/PaddingArg.java diff --git a/src/java/yacx/Program.java b/src/main/java/yacx/Program.java similarity index 100% rename from src/java/yacx/Program.java rename to src/main/java/yacx/Program.java diff --git a/src/java/yacx/ShortArg.java b/src/main/java/yacx/ShortArg.java similarity index 100% rename from src/java/yacx/ShortArg.java rename to src/main/java/yacx/ShortArg.java diff --git a/src/java/yacx/Utils.java b/src/main/java/yacx/Utils.java similarity index 100% rename from src/java/yacx/Utils.java rename to src/main/java/yacx/Utils.java diff --git a/yacx.sh b/yacx.sh index e281dec..cdaa5a0 100755 --- a/yacx.sh +++ b/yacx.sh @@ -1,24 +1,22 @@ #!/bin/bash -PWD=$(pwd) +PWD="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" BUILD_DIR="build" JAVA_BIN="${BUILD_DIR}/java/bin" buildj() { + pushd $PWD mkdir -p $JAVA_BIN cp -R examples/kernels $JAVA_BIN cp examples/java/*.java $JAVA_BIN - pushd $BUILD_DIR - cmake ../ - #make $1 - #make JNIClasses - make yacx-jni - popd + cmake -H. -B$BUILD_DIR + make -C $BUILD_DIR yacx-jni pushd $JAVA_BIN javac *.java -d $PWD -sourcepath $PWD popd + popd echo 'Build finished.' } @@ -27,7 +25,7 @@ exej() { echo "!! parameter needed, select one of the following" find examples/java -type f -iname "*.java" -exec basename '{}' \; | sed 's/\.java$//1' else - pushd $JAVA_BIN + pushd "${PWD}/${JAVA_BIN}" java -ea -Djava.library.path=../../ $1 popd fi @@ -35,10 +33,12 @@ exej() { builds() { buildj + pushd $PWD cp examples/scala/*.scala $JAVA_BIN pushd $JAVA_BIN scalac *.scala popd + popd echo 'Build finished.' } @@ -47,7 +47,7 @@ exes() { echo "!! parameter needed, select one of the following" find examples/scala -type f -iname "*.scala" -exec basename '{}' \; | sed 's/\.java$//1' else - pushd $JAVA_BIN + pushd "${PWD}/${JAVA_BIN}" scala -J-ea -Djava.library.path=../../ $1 popd fi From 1fafe8cce0749c832a1fe55aa62342be3da83a1c Mon Sep 17 00:00:00 2001 From: Lukas Date: Fri, 28 Feb 2020 23:28:24 +0100 Subject: [PATCH 2/4] CExecutor use primitive datatypes implemented --- include/yacx/cexecutor/CProgram.hpp | 28 +++++-- include/yacx/cexecutor/LibaryLoader.hpp | 9 ++- src/cexecutor/CProgram.cpp | 98 +++++++++++++++++++------ src/cexecutor/LibaryLoader.cpp | 11 +-- src/jni/KernelArgJNI.cpp | 7 +- src/jni/KernelArgJNI.hpp | 8 +- src/jni/Utils.cpp | 40 ++++++++++ src/jni/Utils.hpp | 13 +++- src/jni/yacx_ArrayArg.cpp | 2 +- src/jni/yacx_BooleanArg.cpp | 10 +-- src/jni/yacx_ByteArg.cpp | 10 +-- src/jni/yacx_CProgram.cpp | 52 ++++++++----- src/jni/yacx_CProgram.h | 12 ++- src/jni/yacx_DoubleArg.cpp | 10 +-- src/jni/yacx_DoubleArg.h | 2 +- src/jni/yacx_FloatArg.cpp | 12 +-- src/jni/yacx_FloatArg.h | 2 +- src/jni/yacx_HalfArg.cpp | 12 +-- src/jni/yacx_IntArg.cpp | 10 +-- src/jni/yacx_IntArg.h | 2 +- src/jni/yacx_LongArg.cpp | 10 +-- src/jni/yacx_LongArg.h | 2 +- src/jni/yacx_PaddingArg.cpp | 2 +- src/jni/yacx_ShortArg.cpp | 10 +-- src/jni/yacx_ShortArg.h | 2 +- src/main/java/yacx/BooleanArg.java | 2 + src/main/java/yacx/ByteArg.java | 2 + src/main/java/yacx/CProgram.java | 81 +++++++++++++------- src/main/java/yacx/DoubleArg.java | 2 + src/main/java/yacx/Executor.java | 6 +- src/main/java/yacx/FloatArg.java | 2 + src/main/java/yacx/HalfArg.java | 2 + src/main/java/yacx/IntArg.java | 2 + src/main/java/yacx/LongArg.java | 2 + src/main/java/yacx/ShortArg.java | 2 + test/java/yacx/TestC.java | 29 +++++--- test/java/yacx/TestCProgram.java | 50 ++++++++----- test/java/yacx/TestExecutorC.java | 6 +- 38 files changed, 390 insertions(+), 174 deletions(-) diff --git a/include/yacx/cexecutor/CProgram.hpp b/include/yacx/cexecutor/CProgram.hpp index a4be489..3ceda9a 100644 --- a/include/yacx/cexecutor/CProgram.hpp +++ b/include/yacx/cexecutor/CProgram.hpp @@ -2,26 +2,40 @@ #include "../JNIHandle.hpp" #include "LibaryLoader.hpp" +#include "../Options.hpp" #include +#include namespace yacx { class CProgram : public JNIHandle { public: - CProgram(const char *cProgram, const char *functionName, int numberParameters, - const char *compilerWithOptions); + //! Constructs new compiled CProgram.
+ //! The decleration of structs, functions or variables with one of the following name within passed C-Code + //! is permitted:
+ //! op, opfn, execute + //! \param cProgram C-Code for program + //! \param functionName name of c-function, which should be executed + //! \param parameterTypes type of the parameters e.g int or float*
+ //! pointer types can be abbreviated by * + //! \param compiler name of the compiler, which should be used to compile this cProgram + //! \param options options for the compiler + CProgram(const char *cProgram, const char *functionName, std::vector ¶meterTypes, + const char *compiler = "gcc", Options &options = DEFAULT_OPTIONS); ~CProgram(); - void execute(void **arguments, bool* pointerArg); - int getNumberArguments() const { return m_numberArguments; } + //! Executes a the cFunction + //! \param arguments arguments for the cFunction + void execute(std::vector arguments); private: void createSrcFile(const char *cProgram, const char *functionName, - int numberParameters, std::ofstream &fileOut); + std::vector ¶meterTypes, std::ofstream &fileOut); void compile(const char *cProgram, const char *functionName, - int numberParameters, - const char *compilerWithOptions = "gcc -Wall"); + std::vector ¶meterTypes, + std::string &compilerCommand); static int id; + static Options DEFAULT_OPTIONS; int m_numberArguments; struct detail::dynop m_op; std::string m_srcFile; diff --git a/include/yacx/cexecutor/LibaryLoader.hpp b/include/yacx/cexecutor/LibaryLoader.hpp index dbbcc02..0e34893 100644 --- a/include/yacx/cexecutor/LibaryLoader.hpp +++ b/include/yacx/cexecutor/LibaryLoader.hpp @@ -1,20 +1,23 @@ #pragma once +#include + namespace yacx { namespace detail { struct dynop { - void (*op)(void **parameter, bool* pointerArg); + void (*op)(void **parameter); void *libhandle; }; struct opfn { - void (*op)(void **parameter, bool* pointerArg); + void (*op)(void **parameter); }; //! loads a libary and search a specific operation //! \param dest struct to store information //! \param filename name of the libary -void load_op(struct dynop *dest, const char *filename); +//! \param opSymbolName name of the opfn-struct containg the operation, wich should be loaded +void load_op(struct dynop *dest, std::string filename, std::string opSymbolName); //! unloads the libary and cleans the struct //! \param op void unload_op(struct dynop *op); diff --git a/src/cexecutor/CProgram.cpp b/src/cexecutor/CProgram.cpp index 0b4365b..468e489 100644 --- a/src/cexecutor/CProgram.cpp +++ b/src/cexecutor/CProgram.cpp @@ -6,19 +6,30 @@ #include #include -using yacx::loglevel, yacx::CProgram, yacx::detail::load_op, yacx::detail::unload_op, yacx::detail::dynop; +using yacx::loglevel, yacx::CProgram, yacx::Options, yacx::detail::load_op, yacx::detail::unload_op, yacx::detail::dynop; int CProgram::id = 0; -CProgram::CProgram(const char* cProgram, const char* functionName, int numberParameters, - const char* compilerWithOptions) - : m_numberArguments(numberParameters) { +Options createDefaultOptions(){ + Options defaultOptions = Options(); + defaultOptions.insert("-Wall"); + defaultOptions.insert("-Wextra"); + defaultOptions.insert("--pedantic"); + return defaultOptions; +} + +Options CProgram::DEFAULT_OPTIONS = createDefaultOptions(); + +CProgram::CProgram(const char* cProgram, const char* functionName, std::vector ¶meterTypes, + const char *compiler, Options &options) { logger(loglevel::DEBUG) << "creating cProgram " << functionName << " with id: " << id - << ",number of arguments: " << numberParameters << ", compiler: " << compilerWithOptions; + << ", compiler: " << compiler; logger(loglevel::DEBUG1) << "cFunction:\n" << cProgram; id++; + m_numberArguments = parameterTypes.size(); + //filename for srcFile std::stringstream srcFileS; srcFileS << "src_" << functionName << "_" << id << ".c"; @@ -31,11 +42,19 @@ CProgram::CProgram(const char* cProgram, const char* functionName, int numberPar logger(loglevel::DEBUG1) << "compile it to " << m_srcFile << " and " << m_libFile; + //compilerCommand with options + std::stringstream compilerWithOptionsS; + compilerWithOptionsS << compiler << " "; + for (int i = 0; i < options.numOptions(); i++){ + compilerWithOptionsS << options.content()[i] << " "; + } + std::string compilerWithOptions = compilerWithOptionsS.str(); + //compile - compile(cProgram, functionName, numberParameters, compilerWithOptions); + compile(cProgram, functionName, parameterTypes, compilerWithOptions); //open libary - load_op(&m_op, m_libFile.c_str()); + load_op(&m_op, m_libFile, std::string("op") + functionName); } CProgram::~CProgram() { @@ -47,40 +66,66 @@ CProgram::~CProgram() { remove(m_libFile.c_str()); } -void CProgram::createSrcFile(const char* cProgram, const char* functionName, int numberParameters, - std::ofstream& fileOut) { +bool pointerArg(std::string &s){ + for (std::string::reverse_iterator rit=s.rbegin(); rit!=s.rend(); ++rit){ + if (*rit != ' '){ + if (*rit == '*'){ + return true; + } else { + return false; + } + } + } + + throw std::runtime_error(std::string("invalid parameter type: ") + s); +} + +void writeParam(std::vector ¶meterTypes, int i, std::ofstream& fileOut){ + fileOut << "\n "; + if (pointerArg(parameterTypes[i])){ + fileOut << "parameter[" << i << "]"; + } else { + fileOut << "*((" << parameterTypes[i] << "*) " << "parameter[" << i << "])"; + } +} + +void CProgram::createSrcFile(const char* cProgram, const char* functionName, + std::vector ¶meterTypes, std::ofstream& fileOut) { std::string executeFunctionName("execute"); executeFunctionName.append(functionName); - + std::string opfnName("opfn"); + opfnName.append(functionName); + std::string opName("op"); + opName.append(functionName); + //write c function to be executed fileOut << cProgram; fileOut << "\n\n"; //function for start function to be executed fileOut << "void " << executeFunctionName << " ("; - fileOut << "void** parameter, bool* pointerArg"; + fileOut << "void** parameter"; fileOut << ") {\n"; //run function to be executed fileOut << " " << functionName << "("; int i = 0; - for (; i < numberParameters-1; i++){ - fileOut << "\n "; - fileOut << "pointerArg[" << i << "] ? parameter[" << i << "] : *((char*) parameter[" << i <<"]),"; + for (; i < parameterTypes.size()-1; i++){ + writeParam(parameterTypes, i, fileOut); + fileOut << ","; } - fileOut << "\n "; - fileOut << "pointerArg[" << i << "] ? parameter[" << i << "] : *((char*) parameter[" << i <<"])"; + writeParam(parameterTypes, i, fileOut); fileOut << ");\n"; fileOut << "}\n\n"; //struct to store function pointer - fileOut << "struct opfn{ void (*op)(void** parameter);};\n\n"; + fileOut << "struct " << opfnName << "{ void (*op)(void** parameter);};\n\n"; //create instance of struct as interface - fileOut << "struct opfn op = {.op = " << executeFunctionName << "};\n"; + fileOut << "struct " << opfnName << " " << opName << " = {.op = " << executeFunctionName << "};\n"; } -void CProgram::compile(const char* cProgram, const char* functionName, int numberParameters, - const char* compilerWithOptions) { +void CProgram::compile(const char* cProgram, const char* functionName, std::vector ¶meterTypes, + std::string &compilerWithOptions) { logger(loglevel::DEBUG) << "creating source file..."; //create and open output file @@ -88,7 +133,7 @@ void CProgram::compile(const char* cProgram, const char* functionName, int numbe fileOut.open(m_srcFile); //write srcfile - createSrcFile(cProgram, functionName, numberParameters, fileOut); + createSrcFile(cProgram, functionName, parameterTypes, fileOut); //close file fileOut.close(); @@ -109,7 +154,14 @@ void CProgram::compile(const char* cProgram, const char* functionName, int numbe } } -void CProgram::execute(void** arguments, bool* pointerArg) { +void CProgram::execute(std::vector arguments) { logger(loglevel::DEBUG) << "execute CProgram: " << m_srcFile; - m_op.op(arguments, pointerArg); + + if (arguments.size() != m_numberArguments){ + std::stringstream errorS; + errorS << "invalid number of arguments expected: " << m_numberArguments << " found: " << arguments.size(); + throw std::runtime_error(errorS.str()); + } + + m_op.op(&arguments[0]); } \ No newline at end of file diff --git a/src/cexecutor/LibaryLoader.cpp b/src/cexecutor/LibaryLoader.cpp index 11dde62..d976fdb 100644 --- a/src/cexecutor/LibaryLoader.cpp +++ b/src/cexecutor/LibaryLoader.cpp @@ -12,7 +12,7 @@ using yacx::loglevel, yacx::detail::dynop, yacx::detail::opfn; -void yacx::detail::load_op(struct dynop *dest, const char *filename) { +void yacx::detail::load_op(struct dynop *dest, std::string filename, std::string opSymbolName) { //open libary void* handle = dlopen((std::string("./") + filename).c_str(), RTLD_LAZY); char* error = dlerror(); @@ -25,16 +25,17 @@ void yacx::detail::load_op(struct dynop *dest, const char *filename) { } //Search op-struct in libary - void* op = dlsym(handle, "op"); + void* op = dlsym(handle, opSymbolName.c_str()); error = dlerror(); if (op == NULL){ dlclose(handle); if (error != NULL){ - throw std::runtime_error(std::string("error while searching \"op\" in libary with" - "compiled function ") + error); + throw std::runtime_error(std::string("error while searching\"") + std::string(opSymbolName) + + std::string("\" in libary with compiled function ") + error); } else { - throw std::runtime_error("error while searching \"op\" in libary with compiled function"); + throw std::runtime_error(std::string("error while searching\"") + std::string(opSymbolName) + + std::string("\" in libary with compiled function ")); } } diff --git a/src/jni/KernelArgJNI.cpp b/src/jni/KernelArgJNI.cpp index 11c9230..872be8d 100644 --- a/src/jni/KernelArgJNI.cpp +++ b/src/jni/KernelArgJNI.cpp @@ -5,7 +5,7 @@ using jni::KernelArgJNI, jni::KernelArgJNISlice, yacx::KernelArg, std::shared_ptr; -KernelArgJNI::KernelArgJNI(void* const data, size_t size, bool download, bool copy, bool upload) { +KernelArgJNI::KernelArgJNI(void* const data, size_t size, bool download, bool copy, bool upload, std::string type) : m_type(type) { std::shared_ptr hdata(malloc(size), free); m_hdata = hdata; @@ -21,6 +21,7 @@ KernelArgJNI::~KernelArgJNI() { KernelArgJNISlice::KernelArgJNISlice(size_t start, size_t end, KernelArgJNI* arg) : KernelArgJNI(arg->m_hdata, new KernelArg{reinterpret_cast (arg->getHostData()) + start, - end-start, arg->kernelArgPtr()->isDownload(), arg->kernelArgPtr()->isCopy(), true}), - m_offset(static_cast (arg->getHostData()) - static_cast (arg->m_hdata.get()) + end-start, arg->kernelArgPtr()->isDownload(), arg->kernelArgPtr()->isCopy(), true}, + arg->getType()), + m_offset(static_cast (arg->getHostData()) - static_cast (arg->m_hdata.get()) + start) {} diff --git a/src/jni/KernelArgJNI.hpp b/src/jni/KernelArgJNI.hpp index af9a963..10ecefd 100644 --- a/src/jni/KernelArgJNI.hpp +++ b/src/jni/KernelArgJNI.hpp @@ -10,17 +10,19 @@ class KernelArgJNI : yacx::JNIHandle { friend class KernelArgJNISlice; public: - KernelArgJNI(std::shared_ptr hdata, yacx::KernelArg *kernelArg) - : m_hdata(hdata), m_kernelArg(kernelArg){}; - KernelArgJNI(void *data, size_t size, bool download, bool copy, bool upload); + KernelArgJNI(std::shared_ptr hdata, yacx::KernelArg *kernelArg, std::string type) + : m_hdata(hdata), m_kernelArg(kernelArg), m_type(type) {}; + KernelArgJNI(void *data, size_t size, bool download, bool copy, bool upload, std::string type); ~KernelArgJNI(); yacx::KernelArg *kernelArgPtr() { return m_kernelArg; } virtual void *getHostData() const { return m_hdata.get(); } std::shared_ptr getHostDataSharedPointer() { return m_hdata; } + std::string& getType() { return m_type; } private: std::shared_ptr m_hdata; yacx::KernelArg *m_kernelArg; + std::string m_type; }; class KernelArgJNISlice : public KernelArgJNI { diff --git a/src/jni/Utils.cpp b/src/jni/Utils.cpp index 55ffe49..53d1e60 100644 --- a/src/jni/Utils.cpp +++ b/src/jni/Utils.cpp @@ -37,3 +37,43 @@ jobjectArray createStringArray(JNIEnv* env, const char** stringArray, int size) return res; } + +std::vector jStringsToVector(JNIEnv* env, jobjectArray jstringArray) { + CHECK_NULL(jstringArray, {}) + + auto argumentsLength = env->GetArrayLength(jstringArray); + + CHECK_BIGGER(argumentsLength, 0, "illegal array length", {}) + + std::vector args; + args.reserve(argumentsLength); + + for(int i = 0; i < argumentsLength; i++){ + auto jString = static_cast (env->GetObjectArrayElement(jstringArray, i)); + CHECK_NULL(jString, {}) + + auto stringPtr = env->GetStringUTFChars(jString, nullptr); + args.push_back(std::string(stringPtr)); + env->ReleaseStringUTFChars(jString, stringPtr); + } + + return args; +} + +std::string getStaticJString(JNIEnv* env, jclass cls, const char* attributeName) { + jfieldID jfid = env->GetStaticFieldID(cls, attributeName, "Ljava/lang/String;"); + if (jfid == NULL){ + logger(yacx::loglevel::ERROR) << "[JNI ERROR] Cannot find attribute " << attributeName + << " in class " << cls; + throw std::runtime_error(std::string("Cannot find attribute ") + attributeName); + return NULL; + } + + jstring jString = static_cast (env->GetStaticObjectField(cls, jfid)); + + auto stringPtr = env->GetStringUTFChars(jString, nullptr); + auto string = std::string(stringPtr); + env->ReleaseStringUTFChars(jString, stringPtr); + + return string; +} \ No newline at end of file diff --git a/src/jni/Utils.hpp b/src/jni/Utils.hpp index 8e6d274..3409a04 100644 --- a/src/jni/Utils.hpp +++ b/src/jni/Utils.hpp @@ -2,6 +2,15 @@ #include "../../include/yacx/Logger.hpp" #include "Handle.h" +#include + +jclass getClass(JNIEnv *env, const char *name); + +jobjectArray createStringArray(JNIEnv *env, const char **stringArray, int size); + +std::string getStaticJString(JNIEnv* env, jclass cls, const char* attributeName); + +std::vector jStringsToVector(JNIEnv* env, jobjectArray jstringArray); #define CHECK_NULL(object, returnValue) \ if (object == NULL) { \ @@ -81,6 +90,4 @@ return returnValue; \ } -jclass getClass(JNIEnv *env, const char *name); - -jobjectArray createStringArray(JNIEnv *env, const char **stringArray, int size); +#define CTYPE getStaticJString(env, cls, "cType") \ No newline at end of file diff --git a/src/jni/yacx_ArrayArg.cpp b/src/jni/yacx_ArrayArg.cpp index 6f99cef..86c37a0 100644 --- a/src/jni/yacx_ArrayArg.cpp +++ b/src/jni/yacx_ArrayArg.cpp @@ -9,7 +9,7 @@ jlong Java_yacx_ArrayArg_createOutputInternal(JNIEnv* env, jclass cls, jlong jNu BEGIN_TRY CHECK_BIGGER(jNumberBytes, 0, "illegal array length", 0) - KernelArgJNI* kernelArgJNIPtr = new KernelArgJNI{NULL, static_cast (jNumberBytes), true, false, true}; + KernelArgJNI* kernelArgJNIPtr = new KernelArgJNI{NULL, static_cast (jNumberBytes), true, false, true, "*"}; return reinterpret_cast (kernelArgJNIPtr); END_TRY_R("creating output argument", 0) diff --git a/src/jni/yacx_BooleanArg.cpp b/src/jni/yacx_BooleanArg.cpp index 0531a60..894b832 100644 --- a/src/jni/yacx_BooleanArg.cpp +++ b/src/jni/yacx_BooleanArg.cpp @@ -7,12 +7,12 @@ using yacx::KernelArg, jni::KernelArgJNI; jobject JNICALL Java_yacx_BooleanArg_createValue(JNIEnv* env, jclass cls, jboolean jvalue){ BEGIN_TRY - cls = getClass(env, "yacx/KernelArg"); - if (cls == NULL) return NULL; + jclass clsKernelArg = getClass(env, "yacx/KernelArg"); + if (clsKernelArg == NULL) return NULL; - KernelArgJNI* kernelArgPtr = new KernelArgJNI{&jvalue, sizeof(jboolean), false, false, false}; + KernelArgJNI* kernelArgPtr = new KernelArgJNI{&jvalue, sizeof(jboolean), false, false, false, CTYPE}; - return createJNIObject(env, cls, kernelArgPtr); + return createJNIObject(env, clsKernelArg, kernelArgPtr); END_TRY_R("creating BooleanValueArg", NULL) } @@ -25,7 +25,7 @@ jobject Java_yacx_BooleanArg_createInternal (JNIEnv* env, jclass cls, jbooleanAr CHECK_BIGGER(arrayLength, 0, "illegal array length", NULL) - KernelArgJNI* kernelArgPtr = new KernelArgJNI{arrayPtr, arrayLength * sizeof(jboolean), jdownload, true, true}; + KernelArgJNI* kernelArgPtr = new KernelArgJNI{arrayPtr, arrayLength * sizeof(jboolean), jdownload, true, true, CTYPE + "*"}; env->ReleaseBooleanArrayElements(jarray, arrayPtr, JNI_ABORT); diff --git a/src/jni/yacx_ByteArg.cpp b/src/jni/yacx_ByteArg.cpp index 5dcf889..efd1a89 100644 --- a/src/jni/yacx_ByteArg.cpp +++ b/src/jni/yacx_ByteArg.cpp @@ -7,12 +7,12 @@ using yacx::KernelArg, jni::KernelArgJNI; jobject JNICALL Java_yacx_ByteArg_createValue(JNIEnv* env, jclass cls, jbyte jvalue){ BEGIN_TRY - cls = getClass(env, "yacx/KernelArg"); - if (cls == NULL) return NULL; + jclass clsKernelArg = getClass(env, "yacx/KernelArg"); + if (clsKernelArg == NULL) return NULL; - KernelArgJNI* kernelArgPtr = new KernelArgJNI{&jvalue, sizeof(jbyte), false, false, false}; + KernelArgJNI* kernelArgPtr = new KernelArgJNI{&jvalue, sizeof(jbyte), false, false, false, CTYPE}; - return createJNIObject(env, cls, kernelArgPtr); + return createJNIObject(env, clsKernelArg, kernelArgPtr); END_TRY_R("creating ByteValueArg", NULL) } @@ -25,7 +25,7 @@ jobject Java_yacx_ByteArg_createInternal (JNIEnv* env, jclass cls, jbyteArray ja CHECK_BIGGER(arrayLength, 0, "illegal array length", NULL) - KernelArgJNI* kernelArgPtr = new KernelArgJNI{arrayPtr, arrayLength * sizeof(jbyte), jdownload, true, true}; + KernelArgJNI* kernelArgPtr = new KernelArgJNI{arrayPtr, arrayLength * sizeof(jbyte), jdownload, true, true, CTYPE + "*"}; env->ReleaseByteArrayElements(jarray, arrayPtr, JNI_ABORT); diff --git a/src/jni/yacx_CProgram.cpp b/src/jni/yacx_CProgram.cpp index 0bba09d..2dbea43 100644 --- a/src/jni/yacx_CProgram.cpp +++ b/src/jni/yacx_CProgram.cpp @@ -11,31 +11,50 @@ using yacx::KernelArg, jni::KernelArgJNI, yacx::Options, yacx::CProgram; +jobjectArray Java_yacx_CProgram_getTypes (JNIEnv* env, jclass cls, jobjectArray jKernelArgs){ + BEGIN_TRY + auto argsLength = env->GetArrayLength(jKernelArgs); + CHECK_BIGGER(argsLength, 0, "illegal array length", NULL) + + const char* types[argsLength]; + + for(int i = 0; i < argsLength; i++){ + auto jkernelArg = env->GetObjectArrayElement(jKernelArgs, i); + CHECK_NULL(jkernelArg, NULL) + + auto kernelArgJNIPtr = getHandle(env, jkernelArg); + CHECK_NULL(kernelArgJNIPtr, NULL) + + types[i] = kernelArgJNIPtr->getType().c_str(); + } + + return createStringArray(env, types, argsLength); + END_TRY_R("getting types of KernelArgs", NULL) +} + jobject Java_yacx_CProgram_createInternal(JNIEnv* env, jclass cls, jstring jcProgram, jstring jcFunctionName, - jint jnumberParameter, jstring jcompiler, jobject joptions){ + jobjectArray jCtypes, jstring jcompiler, jobject joptions){ BEGIN_TRY CHECK_NULL(jcProgram, NULL) CHECK_NULL(jcFunctionName, NULL) - CHECK_BIGGER(jnumberParameter, 0, "illegal number of parameter", NULL) CHECK_NULL(jcompiler, NULL) CHECK_NULL(joptions, NULL) auto cProgram = env->GetStringUTFChars(jcProgram, nullptr); auto cFunctionName = env->GetStringUTFChars(jcFunctionName, nullptr); + auto cTypes = jStringsToVector(env, jCtypes); auto compiler = env->GetStringUTFChars(jcompiler, nullptr); + if (cTypes.empty()) return NULL; + auto optionsPtr = getHandle(env, joptions); CHECK_NULL(optionsPtr, NULL); - std::stringstream compilerWithOptionsS; - compilerWithOptionsS << compiler << " "; - for (int i = 0; i < optionsPtr->numOptions(); i++){ - compilerWithOptionsS << optionsPtr->content()[i] << " "; - } - std::string tmp = compilerWithOptionsS.str(); - auto compilerWithOptions = tmp.c_str(); + CProgram* cProgramPtr = new CProgram{cProgram, cFunctionName, cTypes, compiler, *optionsPtr}; - CProgram* cProgramPtr = new CProgram{cProgram, cFunctionName, jnumberParameter, compilerWithOptions}; + env->ReleaseStringUTFChars(jcProgram, cProgram); + env->ReleaseStringUTFChars(jcFunctionName, cFunctionName); + env->ReleaseStringUTFChars(jcompiler, compiler); return createJNIObject(env, cls, cProgramPtr); END_TRY_R("creating cProgram", NULL) @@ -46,14 +65,13 @@ void Java_yacx_CProgram_execute(JNIEnv* env, jobject obj, jobjectArray jKernelAr CHECK_NULL(jKernelArgs, ) auto cProgramPtr = getHandle(env, obj); - CHECK_NULL(cProgramPtr, ); + CHECK_NULL(cProgramPtr, ) auto argumentsLength = env->GetArrayLength(jKernelArgs); - void* argsPtr[argumentsLength]; - CHECK_BIGGER(argumentsLength, 0, "illegal array length", ) - CHECK_BIGGER(argumentsLength, cProgramPtr->getNumberArguments()-1, "illegal number of arguments", ) - CHECK_BIGGER(cProgramPtr->getNumberArguments(), argumentsLength-1, "illegal number of arguments", ) + + std::vector arguments; + arguments.resize(argumentsLength); for(int i = 0; i < argumentsLength; i++){ auto jkernelArg = env->GetObjectArrayElement(jKernelArgs, i); @@ -62,9 +80,9 @@ void Java_yacx_CProgram_execute(JNIEnv* env, jobject obj, jobjectArray jKernelAr auto kernelArgJNIPtr = getHandle(env, jkernelArg); CHECK_NULL(kernelArgJNIPtr, ) - argsPtr[i] = kernelArgJNIPtr->getHostData(); + arguments[i] = kernelArgJNIPtr->getHostData(); } - //cProgramPtr->execute(argsPtr); + cProgramPtr->execute(arguments); END_TRY("executing cProgram") } diff --git a/src/jni/yacx_CProgram.h b/src/jni/yacx_CProgram.h index ac1c3ec..20896fd 100644 --- a/src/jni/yacx_CProgram.h +++ b/src/jni/yacx_CProgram.h @@ -7,13 +7,21 @@ #ifdef __cplusplus extern "C" { #endif +/* + * Class: yacx_CProgram + * Method: getTypes + * Signature: ([Lyacx/KernelArg;)[Ljava/lang/String; + */ +JNIEXPORT jobjectArray JNICALL Java_yacx_CProgram_getTypes + (JNIEnv *, jclass, jobjectArray); + /* * Class: yacx_CProgram * Method: createInternal - * Signature: (Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Lyacx/Options;)Lyacx/CProgram; + * Signature: (Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Lyacx/Options;)Lyacx/CProgram; */ JNIEXPORT jobject JNICALL Java_yacx_CProgram_createInternal - (JNIEnv *, jclass, jstring, jstring, jint, jstring, jobject); + (JNIEnv *, jclass, jstring, jstring, jobjectArray, jstring, jobject); /* * Class: yacx_CProgram diff --git a/src/jni/yacx_DoubleArg.cpp b/src/jni/yacx_DoubleArg.cpp index e0c7834..95ce811 100644 --- a/src/jni/yacx_DoubleArg.cpp +++ b/src/jni/yacx_DoubleArg.cpp @@ -7,12 +7,12 @@ using yacx::KernelArg, jni::KernelArgJNI; jobject JNICALL Java_yacx_DoubleArg_createValue(JNIEnv* env, jclass cls, jdouble jvalue){ BEGIN_TRY - cls = getClass(env, "yacx/KernelArg"); - if (cls == NULL) return NULL; + jclass clsKernelArg = getClass(env, "yacx/KernelArg"); + if (clsKernelArg == NULL) return NULL; - KernelArgJNI* kernelArgPtr = new KernelArgJNI{&jvalue, sizeof(jdouble), false, false, false}; + KernelArgJNI* kernelArgPtr = new KernelArgJNI{&jvalue, sizeof(jdouble), false, false, false, CTYPE}; - return createJNIObject(env, cls, kernelArgPtr); + return createJNIObject(env, clsKernelArg, kernelArgPtr); END_TRY_R("creating DoubleValueArg", NULL) } @@ -25,7 +25,7 @@ jobject Java_yacx_DoubleArg_createInternal (JNIEnv* env, jclass cls, jdoubleArra CHECK_BIGGER(arrayLength, 0, "illegal array length", NULL) - KernelArgJNI* kernelArgPtr = new KernelArgJNI{arrayPtr, arrayLength * sizeof(jdouble), jdownload, true, true}; + KernelArgJNI* kernelArgPtr = new KernelArgJNI{arrayPtr, arrayLength * sizeof(jdouble), jdownload, true, true, CTYPE + "*"}; env->ReleaseDoubleArrayElements(jarray, arrayPtr, JNI_ABORT); diff --git a/src/jni/yacx_DoubleArg.h b/src/jni/yacx_DoubleArg.h index 078ebfe..94aff76 100644 --- a/src/jni/yacx_DoubleArg.h +++ b/src/jni/yacx_DoubleArg.h @@ -8,7 +8,7 @@ extern "C" { #endif #undef yacx_DoubleArg_SIZE_BYTES -#define yacx_DoubleArg_SIZE_BYTES 1LL +#define yacx_DoubleArg_SIZE_BYTES 8LL /* * Class: yacx_DoubleArg * Method: createValue diff --git a/src/jni/yacx_FloatArg.cpp b/src/jni/yacx_FloatArg.cpp index f4f20f7..26fc00c 100644 --- a/src/jni/yacx_FloatArg.cpp +++ b/src/jni/yacx_FloatArg.cpp @@ -8,12 +8,12 @@ using yacx::KernelArg, jni::KernelArgJNI, yacx::convertFtoH; jobject JNICALL Java_yacx_FloatArg_createValue(JNIEnv* env, jclass cls, jfloat jvalue){ BEGIN_TRY - cls = getClass(env, "yacx/KernelArg"); - if (cls == NULL) return NULL; + jclass clsKernelArg = getClass(env, "yacx/KernelArg"); + if (clsKernelArg == NULL) return NULL; - KernelArgJNI* kernelArgPtr = new KernelArgJNI{&jvalue, sizeof(jfloat), false, false, false}; + KernelArgJNI* kernelArgPtr = new KernelArgJNI{&jvalue, sizeof(jfloat), false, false, false, CTYPE}; - return createJNIObject(env, cls, kernelArgPtr); + return createJNIObject(env, clsKernelArg, kernelArgPtr); END_TRY_R("creating FloatValueArg", NULL) } @@ -26,7 +26,7 @@ jobject Java_yacx_FloatArg_createInternal (JNIEnv* env, jclass cls, jfloatArray CHECK_BIGGER(arrayLength, 0, "illegal array length", NULL) - KernelArgJNI* kernelArgPtr = new KernelArgJNI{arrayPtr, arrayLength * sizeof(jfloat), jdownload, true, true}; + KernelArgJNI* kernelArgPtr = new KernelArgJNI{arrayPtr, arrayLength * sizeof(jfloat), jdownload, true, true, CTYPE + "*"}; env->ReleaseFloatArrayElements(jarray, arrayPtr, JNI_ABORT); @@ -63,7 +63,7 @@ jobject Java_yacx_FloatArg_asHalfArg(JNIEnv* env, jobject obj){ if (cls == NULL) return NULL; KernelArgJNI* newkernelArgJNIPtr = new KernelArgJNI{NULL, dataSize/2, - kernelArgPtr->isDownload(), kernelArgPtr->isCopy(), true}; + kernelArgPtr->isDownload(), kernelArgPtr->isCopy(), true, CTYPE + "*"}; convertFtoH(data, newkernelArgJNIPtr->getHostData(), dataSize/sizeof(jfloat)); diff --git a/src/jni/yacx_FloatArg.h b/src/jni/yacx_FloatArg.h index 96ee267..7bf24c3 100644 --- a/src/jni/yacx_FloatArg.h +++ b/src/jni/yacx_FloatArg.h @@ -8,7 +8,7 @@ extern "C" { #endif #undef yacx_FloatArg_SIZE_BYTES -#define yacx_FloatArg_SIZE_BYTES 1LL +#define yacx_FloatArg_SIZE_BYTES 4LL /* * Class: yacx_FloatArg * Method: createValue diff --git a/src/jni/yacx_HalfArg.cpp b/src/jni/yacx_HalfArg.cpp index 70bed5a..8393f3c 100644 --- a/src/jni/yacx_HalfArg.cpp +++ b/src/jni/yacx_HalfArg.cpp @@ -8,13 +8,13 @@ using yacx::KernelArg, jni::KernelArgJNI, yacx::convertHtoF, yacx::convertFtoH; jobject JNICALL Java_yacx_HalfArg_createValue(JNIEnv* env, jclass cls, jfloat jvalue){ BEGIN_TRY - cls = getClass(env, "yacx/KernelArg"); - if (cls == NULL) return NULL; + jclass clsKernelArg = getClass(env, "yacx/KernelArg"); + if (clsKernelArg == NULL) return NULL; - KernelArgJNI* kernelArgPtr = new KernelArgJNI{NULL, sizeof(jfloat)/2, false, false, false}; + KernelArgJNI* kernelArgPtr = new KernelArgJNI{NULL, sizeof(jfloat)/2, false, false, false, CTYPE}; convertFtoH(&jvalue, kernelArgPtr->getHostData(), 1); - return createJNIObject(env, cls, kernelArgPtr); + return createJNIObject(env, clsKernelArg, kernelArgPtr); END_TRY_R("creating HalfValueArg", NULL) } @@ -27,7 +27,7 @@ jobject Java_yacx_HalfArg_createInternal (JNIEnv* env, jclass cls, jfloatArray j CHECK_BIGGER(arrayLength, 0, "illegal array length", NULL) - KernelArgJNI* kernelArgPtr = new KernelArgJNI{NULL, arrayLength * (sizeof(jfloat)/2), jdownload, true, true}; + KernelArgJNI* kernelArgPtr = new KernelArgJNI{NULL, arrayLength * (sizeof(jfloat)/2), jdownload, true, true, CTYPE + "*"}; convertFtoH(arrayPtr, kernelArgPtr->getHostData(), arrayLength); env->ReleaseFloatArrayElements(jarray, arrayPtr, JNI_ABORT); @@ -71,7 +71,7 @@ jobject Java_yacx_HalfArg_asFloatArg(JNIEnv* env, jobject obj){ if (cls == NULL) return NULL; KernelArgJNI* newkernelArgJNIPtr = new KernelArgJNI{NULL, dataSize*2, - kernelArgPtr->isDownload(), kernelArgPtr->isCopy(), true}; + kernelArgPtr->isDownload(), kernelArgPtr->isCopy(), true, CTYPE + "*"}; convertHtoF(data, newkernelArgJNIPtr->getHostData(), dataSize/2); diff --git a/src/jni/yacx_IntArg.cpp b/src/jni/yacx_IntArg.cpp index 40886f7..5484eac 100644 --- a/src/jni/yacx_IntArg.cpp +++ b/src/jni/yacx_IntArg.cpp @@ -7,12 +7,12 @@ using yacx::KernelArg, jni::KernelArgJNI; jobject JNICALL Java_yacx_IntArg_createValue(JNIEnv* env, jclass cls, jint jvalue){ BEGIN_TRY - cls = getClass(env, "yacx/KernelArg"); - if (cls == NULL) return NULL; + jclass clsKernelArg = getClass(env, "yacx/KernelArg"); + if (clsKernelArg == NULL) return NULL; - KernelArgJNI* kernelArgPtr = new KernelArgJNI{&jvalue, sizeof(jint), false, false, false}; + KernelArgJNI* kernelArgPtr = new KernelArgJNI{&jvalue, sizeof(jint), false, false, false, CTYPE}; - return createJNIObject(env, cls, kernelArgPtr); + return createJNIObject(env, clsKernelArg, kernelArgPtr); END_TRY_R("creating IntValueArg", NULL) } @@ -25,7 +25,7 @@ jobject Java_yacx_IntArg_createInternal (JNIEnv* env, jclass cls, jintArray jarr CHECK_BIGGER(arrayLength, 0, "illegal array length", NULL) - KernelArgJNI* kernelArgPtr = new KernelArgJNI{arrayPtr, arrayLength * sizeof(jint), jdownload, true, true}; + KernelArgJNI* kernelArgPtr = new KernelArgJNI{arrayPtr, arrayLength * sizeof(jint), jdownload, true, true, CTYPE + "*"}; env->ReleaseIntArrayElements(jarray, arrayPtr, JNI_ABORT); diff --git a/src/jni/yacx_IntArg.h b/src/jni/yacx_IntArg.h index cb3d33e..7c51940 100644 --- a/src/jni/yacx_IntArg.h +++ b/src/jni/yacx_IntArg.h @@ -8,7 +8,7 @@ extern "C" { #endif #undef yacx_IntArg_SIZE_BYTES -#define yacx_IntArg_SIZE_BYTES 1LL +#define yacx_IntArg_SIZE_BYTES 4LL /* * Class: yacx_IntArg * Method: createValue diff --git a/src/jni/yacx_LongArg.cpp b/src/jni/yacx_LongArg.cpp index 3730916..f6e1a2c 100644 --- a/src/jni/yacx_LongArg.cpp +++ b/src/jni/yacx_LongArg.cpp @@ -7,12 +7,12 @@ using yacx::KernelArg, jni::KernelArgJNI; jobject JNICALL Java_yacx_LongArg_createValue(JNIEnv* env, jclass cls, jlong jvalue){ BEGIN_TRY - cls = getClass(env, "yacx/KernelArg"); - if (cls == NULL) return NULL; + jclass clsKernelArg = getClass(env, "yacx/KernelArg"); + if (clsKernelArg == NULL) return NULL; - KernelArgJNI* kernelArgPtr = new KernelArgJNI{&jvalue, sizeof(jlong), false, false, false}; + KernelArgJNI* kernelArgPtr = new KernelArgJNI{&jvalue, sizeof(jlong), false, false, false, CTYPE}; - return createJNIObject(env, cls, kernelArgPtr); + return createJNIObject(env, clsKernelArg, kernelArgPtr); END_TRY_R("creating LongValueArg", NULL) } @@ -25,7 +25,7 @@ jobject Java_yacx_LongArg_createInternal (JNIEnv* env, jclass cls, jlongArray ja CHECK_BIGGER(arrayLength, 0, "illegal array length", NULL) - KernelArgJNI* kernelArgPtr = new KernelArgJNI{arrayPtr, arrayLength * sizeof(jlong), jdownload, true, true}; + KernelArgJNI* kernelArgPtr = new KernelArgJNI{arrayPtr, arrayLength * sizeof(jlong), jdownload, true, true, CTYPE + "*"}; env->ReleaseLongArrayElements(jarray, arrayPtr, JNI_ABORT); diff --git a/src/jni/yacx_LongArg.h b/src/jni/yacx_LongArg.h index d4fa3cc..19d1b7a 100644 --- a/src/jni/yacx_LongArg.h +++ b/src/jni/yacx_LongArg.h @@ -8,7 +8,7 @@ extern "C" { #endif #undef yacx_LongArg_SIZE_BYTES -#define yacx_LongArg_SIZE_BYTES 1LL +#define yacx_LongArg_SIZE_BYTES 8LL /* * Class: yacx_LongArg * Method: createValue diff --git a/src/jni/yacx_PaddingArg.cpp b/src/jni/yacx_PaddingArg.cpp index 617a22e..36cdd67 100644 --- a/src/jni/yacx_PaddingArg.cpp +++ b/src/jni/yacx_PaddingArg.cpp @@ -24,7 +24,7 @@ jobject Java_yacx_PaddingArg_createMatrixPaddingInternal(JNIEnv* env, jclass cls static_cast (jpaddingValue), jrowsArg, jcolumnsArg, jrowsNew, jcolumnsNew}; KernelArgJNI* newKernelArgJNIPtr = new KernelArgJNI{kernelArgJNIPtr->getHostDataSharedPointer(), - newKernelArgPtr}; + newKernelArgPtr, kernelArgJNIPtr->getType()}; return createJNIObject(env, cls, newKernelArgJNIPtr); END_TRY_R("create PaddinArg", NULL) diff --git a/src/jni/yacx_ShortArg.cpp b/src/jni/yacx_ShortArg.cpp index 4dc2c0d..909b4cf 100644 --- a/src/jni/yacx_ShortArg.cpp +++ b/src/jni/yacx_ShortArg.cpp @@ -7,12 +7,12 @@ using yacx::KernelArg, jni::KernelArgJNI; jobject JNICALL Java_yacx_ShortArg_createValue(JNIEnv* env, jclass cls, jshort jvalue){ BEGIN_TRY - cls = getClass(env, "yacx/KernelArg"); - if (cls == NULL) return NULL; + jclass clsKernelArg = getClass(env, "yacx/KernelArg"); + if (clsKernelArg == NULL) return NULL; - KernelArgJNI* kernelArgPtr = new KernelArgJNI{&jvalue, sizeof(jshort), false, false, false}; + KernelArgJNI* kernelArgPtr = new KernelArgJNI{&jvalue, sizeof(jshort), false, false, false, CTYPE}; - return createJNIObject(env, cls, kernelArgPtr); + return createJNIObject(env, clsKernelArg, kernelArgPtr); END_TRY_R("creating ShortValueArg", NULL) } @@ -25,7 +25,7 @@ jobject Java_yacx_ShortArg_createInternal (JNIEnv* env, jclass cls, jshortArray CHECK_BIGGER(arrayLength, 0, "illegal array length", NULL) - KernelArgJNI* kernelArgPtr = new KernelArgJNI{arrayPtr, arrayLength * sizeof(jshort), jdownload, true, true}; + KernelArgJNI* kernelArgPtr = new KernelArgJNI{arrayPtr, arrayLength * sizeof(jshort), jdownload, true, true, CTYPE + "*"}; env->ReleaseShortArrayElements(jarray, arrayPtr, JNI_ABORT); diff --git a/src/jni/yacx_ShortArg.h b/src/jni/yacx_ShortArg.h index c255e80..2984776 100644 --- a/src/jni/yacx_ShortArg.h +++ b/src/jni/yacx_ShortArg.h @@ -8,7 +8,7 @@ extern "C" { #endif #undef yacx_ShortArg_SIZE_BYTES -#define yacx_ShortArg_SIZE_BYTES 1LL +#define yacx_ShortArg_SIZE_BYTES 2LL /* * Class: yacx_ShortArg * Method: createValue diff --git a/src/main/java/yacx/BooleanArg.java b/src/main/java/yacx/BooleanArg.java index b090b77..8b26819 100644 --- a/src/main/java/yacx/BooleanArg.java +++ b/src/main/java/yacx/BooleanArg.java @@ -13,6 +13,8 @@ public class BooleanArg extends ArrayArg { */ public final static long SIZE_BYTES = 1; + private final static String cType = "bool"; + /** * Create a boolean-value-argument. * diff --git a/src/main/java/yacx/ByteArg.java b/src/main/java/yacx/ByteArg.java index c6acdf6..396f75b 100644 --- a/src/main/java/yacx/ByteArg.java +++ b/src/main/java/yacx/ByteArg.java @@ -13,6 +13,8 @@ public class ByteArg extends ArrayArg { */ public final static long SIZE_BYTES = 1; + private final static String cType = "uint8_t"; + /** * Create a byte-value-argument. * diff --git a/src/main/java/yacx/CProgram.java b/src/main/java/yacx/CProgram.java index deb456c..1767233 100644 --- a/src/main/java/yacx/CProgram.java +++ b/src/main/java/yacx/CProgram.java @@ -1,60 +1,87 @@ package yacx; /** - * + * Class to compile and execute a C-Program. */ public class CProgram extends JNIHandle { private static final String DEFAULT_COMPILER = "gcc"; - private static final String DEFAULT_OPTIONS = "-Wall -Wextra"; + private static final String DEFAULT_OPTIONS = "-Wall -Wextra --pedantic"; + + // This header is needed for the primtive datatypes corresponding to the CTYPE + // of KernelArgs + // e.g. int32_t for a IntArg + private static final String HEADER_FOR_DATATYPES = "#include \n\n"; /** - * Compile a load c cProgram. + * Compile a load c cProgram.
+ * The decleration of structs, functions or variables with one of the following + * name within passed C-Code is permitted:
+ * op, opfn, execute * - * @param cProgram string containing the cProgram - * @param functionName name of the cFunction which should be executed - * @param numberParameter number of parameters for the cFunction + * @param cProgram string containing the cProgram + * @param functionName name of the cFunction which should be executed + * @param parameterTypes types of parameter e.g. int or float*
+ * pointer types can be abbreviated by * * @return created and compiled cProgram */ - public static CProgram create(String cProgram, String functionName, int numberParameter) { - return create(cProgram, functionName, numberParameter, DEFAULT_COMPILER); + public static CProgram create(String cProgram, String functionName, String[] parameterTypes) { + return create(cProgram, functionName, parameterTypes, DEFAULT_COMPILER); } /** - * Compile a load c cProgram. + * Compile a load c cProgram.
+ * The decleration of structs, functions or variables with one of the following + * name within passed C-Code is permitted:
+ * op, opfn, execute * - * @param cProgram string containing the cProgram - * @param functionName name of the cFunction which should be executed - * @param numberParameter number of parameters for the cFunction - * @param compiler name of the compiler for compiling the cProgram + * @param cProgram string containing the cProgram + * @param functionName name of the cFunction which should be executed + * @param parameterTypes types of parameter e.g. int or float*
+ * pointer types can be abbreviated by * + * @param compiler name of the compiler for compiling the cProgram * @return created and compiled cProgram */ - public static CProgram create(String cProgram, String functionName, int numberParameter, String compiler) { - return create(cProgram, functionName, numberParameter, DEFAULT_COMPILER, - Options.createOptions(DEFAULT_OPTIONS)); + public static CProgram create(String cProgram, String functionName, String[] parameterTypes, String compiler) { + return create(cProgram, functionName, parameterTypes, DEFAULT_COMPILER, Options.createOptions(DEFAULT_OPTIONS)); } /** - * Compile a load c cProgram. + * Compile a load c cProgram.
+ * The decleration of structs, functions or variables with one of the following + * name within passed C-Code is permitted:
+ * op, opfn, execute * - * @param cProgram string containing the cProgram - * @param functionName name of the cFunction which should be executed - * @param numberParameter number of parameters for the cFunction - * @param compiler name of the compiler for compiling the cProgram - * @param options options for the passed compiler + * @param cProgram string containing the cProgram + * @param functionName name of the cFunction which should be executed + * @param parameterTypes types of parameter e.g. int or float*
+ * pointer types can be abbreviated by * + * @param compiler name of the compiler for compiling the cProgram + * @param options options for the passed compiler * @return created and compiled cProgram */ - public static CProgram create(String cProgram, String functionName, int numberParameter, String compiler, + public static CProgram create(String cProgram, String functionName, String[] parameterTypes, String compiler, Options options) { - assert (cProgram != null && !cProgram.equals("")); + if (cProgram == null) + throw new NullPointerException(); + + assert (!cProgram.equals("")); assert (functionName != null && !functionName.equals("")); - assert (numberParameter > 0); + assert (parameterTypes.length > 0); assert (compiler != null && !compiler.equals("")); assert (options != null); - return createInternal(cProgram, functionName, numberParameter, compiler, options); + return createInternal(HEADER_FOR_DATATYPES + cProgram, functionName, parameterTypes, compiler, options); } - private static native CProgram createInternal(String cProgram, String functionName, int numberParameter, + /** + * Return the Ctypes of the passed array of KernelArgs. + * + * @param args kernelArgs + * @return array with corresponding Ctypes + */ + public static native String[] getTypes(KernelArg[] args); + + private static native CProgram createInternal(String cProgram, String functionName, String[] parameterTypes, String compiler, Options options); /** diff --git a/src/main/java/yacx/DoubleArg.java b/src/main/java/yacx/DoubleArg.java index 9a1617f..a2da4a9 100644 --- a/src/main/java/yacx/DoubleArg.java +++ b/src/main/java/yacx/DoubleArg.java @@ -13,6 +13,8 @@ public class DoubleArg extends ArrayArg { */ public final static long SIZE_BYTES = 8; + private final static String cType = "double"; + /** * Create a double-value-argument. * diff --git a/src/main/java/yacx/Executor.java b/src/main/java/yacx/Executor.java index 1d3ca66..0eee3a0 100644 --- a/src/main/java/yacx/Executor.java +++ b/src/main/java/yacx/Executor.java @@ -27,7 +27,7 @@ public static void loadLibary() { * @return execution time in milliseconds (wallclock time) */ public static long executeC(String cProgram, String functionName, KernelArg... args) { - CProgram cProg = CProgram.create(cProgram, functionName, args.length); + CProgram cProg = CProgram.create(cProgram, functionName, CProgram.getTypes(args)); long t0 = System.currentTimeMillis(); cProg.execute(args); @@ -44,7 +44,7 @@ public static long executeC(String cProgram, String functionName, KernelArg... a * @return execution time in milliseconds (wallclock time) */ public static long executeC(String cProgram, String functionName, String compiler, KernelArg... args) { - CProgram cProg = CProgram.create(cProgram, functionName, args.length, compiler); + CProgram cProg = CProgram.create(cProgram, functionName, CProgram.getTypes(args), compiler); long t0 = System.currentTimeMillis(); cProg.execute(args); @@ -63,7 +63,7 @@ public static long executeC(String cProgram, String functionName, String compile */ public static long executeC(String cProgram, String functionName, String compiler, Options options, KernelArg... args) { - CProgram cProg = CProgram.create(cProgram, functionName, args.length, compiler, options); + CProgram cProg = CProgram.create(cProgram, functionName, CProgram.getTypes(args), compiler, options); long t0 = System.currentTimeMillis(); cProg.execute(args); diff --git a/src/main/java/yacx/FloatArg.java b/src/main/java/yacx/FloatArg.java index fdb5a6a..54f84f3 100644 --- a/src/main/java/yacx/FloatArg.java +++ b/src/main/java/yacx/FloatArg.java @@ -13,6 +13,8 @@ public class FloatArg extends ArrayArg { */ public final static long SIZE_BYTES = 4; + private final static String cType = "float"; + /** * Create a float-value-argument. * diff --git a/src/main/java/yacx/HalfArg.java b/src/main/java/yacx/HalfArg.java index 31ba44b..5a16df7 100644 --- a/src/main/java/yacx/HalfArg.java +++ b/src/main/java/yacx/HalfArg.java @@ -16,6 +16,8 @@ public class HalfArg extends ArrayArg { */ public final static long SIZE_BYTES = 2; + private final static String cType = ""; // there exist no cType for half + /** * Convert the float to a half and create a half-value-argument. * diff --git a/src/main/java/yacx/IntArg.java b/src/main/java/yacx/IntArg.java index a9aeb4d..723d949 100644 --- a/src/main/java/yacx/IntArg.java +++ b/src/main/java/yacx/IntArg.java @@ -13,6 +13,8 @@ public class IntArg extends ArrayArg { */ public final static long SIZE_BYTES = 4; + private final static String cType = "int32_t"; + /** * Create a int-value-argument. * diff --git a/src/main/java/yacx/LongArg.java b/src/main/java/yacx/LongArg.java index 51066cf..6eb6c88 100644 --- a/src/main/java/yacx/LongArg.java +++ b/src/main/java/yacx/LongArg.java @@ -13,6 +13,8 @@ public class LongArg extends ArrayArg { */ public final static long SIZE_BYTES = 8; + private final static String cType = "int64_t"; + /** * Create a long-value-argument. * diff --git a/src/main/java/yacx/ShortArg.java b/src/main/java/yacx/ShortArg.java index 5bf157c..2615d96 100644 --- a/src/main/java/yacx/ShortArg.java +++ b/src/main/java/yacx/ShortArg.java @@ -13,6 +13,8 @@ public class ShortArg extends ArrayArg { */ public final static long SIZE_BYTES = 2; + private final static String cType = "int16_t"; + /** * Create a short-value-argument. * diff --git a/test/java/yacx/TestC.java b/test/java/yacx/TestC.java index 1fca94e..87d16ea 100644 --- a/test/java/yacx/TestC.java +++ b/test/java/yacx/TestC.java @@ -3,8 +3,9 @@ import org.junit.jupiter.api.BeforeAll; public class TestC { - static String addIntPtrs, saxpy; + static String addInts, saxpy; static KernelArg[] addIntArgs, saxpyArgs; + static String[] addIntTypes, saxpyTypes; @BeforeAll static void initLibary() { @@ -14,22 +15,32 @@ static void initLibary() { @BeforeAll static void initCFunctions() { - addIntPtrs = "void addIntPtrs(int* a, int* b, int* result){\n" + " *result = *a + *b;\n" + "}\n" + "\n"; - - saxpy = "#include \n" + "void saxpy(float* a, float *x, float *y, float *out, int* n) {\n" - + " for (int i = 0; i < *n; i++) {\n" + " out[i] = *a * x[i] + y[i];\n" + " }\n" + "}"; + addInts = "void addInts(int32_t a, int32_t b, int32_t* result){\n" + + " *result = a + b;\n" + + "}\n" + + "\n"; + + saxpy = "#include \n" + + "void saxpy(float a, float *x, float *y, float *out, int32_t n) {\n" + + " for (int i = 0; i < n; i++) {\n" + + " out[i] = a * x[i] + y[i];\n" + + " }\n" + + "}"; addIntArgs = new KernelArg[3]; saxpyArgs = new KernelArg[5]; - addIntArgs[0] = IntArg.create(2); - addIntArgs[1] = IntArg.create(3); + addIntArgs[0] = IntArg.createValue(2); + addIntArgs[1] = IntArg.createValue(3); addIntArgs[2] = IntArg.createOutput(1); - saxpyArgs[0] = FloatArg.create(2f); + saxpyArgs[0] = FloatArg.createValue(2f); saxpyArgs[1] = FloatArg.create(1f, 2f, 3.6f); saxpyArgs[2] = FloatArg.create(2f, 1f, 0f); saxpyArgs[3] = FloatArg.createOutput(3); - saxpyArgs[4] = IntArg.create(3); + saxpyArgs[4] = IntArg.createValue(3); + + addIntTypes = new String[] { "int32_t", "int32_t", "int32_t*" }; + saxpyTypes = new String[] { "float", "float*", "float*", "float*", "int32_t" }; } } diff --git a/test/java/yacx/TestCProgram.java b/test/java/yacx/TestCProgram.java index 2f13c39..4c574f7 100644 --- a/test/java/yacx/TestCProgram.java +++ b/test/java/yacx/TestCProgram.java @@ -3,6 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; @@ -11,39 +12,54 @@ @TestMethodOrder(OrderAnnotation.class) public class TestCProgram extends TestC { - static String addIntPtrsInvalid = "void addIntPtrs(int* a, int* b, int* result){\n" + " result = *a + *c;\n" + static String addIntsInvalid = "void addInts(int32_t a, int32_t b, int32_t* result){\n" + + " *result = a + c;\n" + "}"; static CProgram addIntC, saxpyC; @Test @Order(1) + void testGetTypes() { + String[] types = CProgram.getTypes(addIntArgs); + assertEquals(types.length, 3); + assertEquals("int32_t", types[0]); + assertEquals("int32_t", types[1]); + assertTrue(types[2].endsWith("*")); + + types = CProgram.getTypes(saxpyArgs); + assertEquals(types.length, 5); + assertEquals("float", types[0]); + assertTrue(types[1].endsWith("*")); + assertTrue(types[2].endsWith("*")); + assertTrue(types[3].endsWith("*")); + assertEquals("int32_t", types[4]); + } + + @Test + @Order(2) void testCompileInvalid() { assertThrows(NullPointerException.class, () -> { - CProgram.create(null, "addIntPtrs", 3); + CProgram.create(null, "addInts", addIntTypes); }); assertThrows(NullPointerException.class, () -> { - CProgram.create(addIntPtrs, null, 3); + CProgram.create(addInts, null, addIntTypes); }); assertThrows(IllegalArgumentException.class, () -> { - CProgram.create(addIntPtrs, "addIntPtrs", -17); - }); - - assertThrows(IllegalArgumentException.class, () -> { - CProgram.create(addIntPtrs, "addIntPtrs", 0); + CProgram.create(addInts, "addInts", new String[0]); }); assertThrows(ExecutorFailureException.class, () -> { - CProgram.create(addIntPtrsInvalid, "addIntPtrs", 3); + CProgram.create(addIntsInvalid, "addInts", addIntTypes); }); } @Test - @Order(2) + @Order(3) void testCompile() { - addIntC = CProgram.create(addIntPtrs, "addIntPtrs", 3); + addIntC = CProgram.create(addInts, "addInts", addIntTypes); String compiler = "gcc"; Options options = Options.createOptions(); @@ -51,28 +67,28 @@ void testCompile() { options.insert("-pedantic"); ; - saxpyC = CProgram.create(saxpy, "saxpy", 5, compiler); - saxpyC = CProgram.create(saxpy, "saxpy", 5, compiler, options); + saxpyC = CProgram.create(saxpy, "saxpy", saxpyTypes, compiler); + saxpyC = CProgram.create(saxpy, "saxpy", saxpyTypes, compiler, options); } @Test - @Order(3) + @Order(4) void testExecuteInvalid() { assertThrows(IllegalArgumentException.class, () -> { addIntC.execute(); }); - assertThrows(IllegalArgumentException.class, () -> { + assertThrows(ExecutorFailureException.class, () -> { saxpyC.execute(saxpyArgs[0], saxpyArgs[1], saxpyArgs[2], saxpyArgs[3]); }); - assertThrows(IllegalArgumentException.class, () -> { + assertThrows(ExecutorFailureException.class, () -> { addIntC.execute(addIntArgs[0], addIntArgs[1], addIntArgs[2], addIntArgs[2]); }); } @Test - @Order(4) + @Order(5) void testExecute() { addIntC.execute(addIntArgs); assertEquals(5, ((IntArg) addIntArgs[2]).asIntArray()[0]); diff --git a/test/java/yacx/TestExecutorC.java b/test/java/yacx/TestExecutorC.java index ec8199c..eebfca0 100644 --- a/test/java/yacx/TestExecutorC.java +++ b/test/java/yacx/TestExecutorC.java @@ -8,7 +8,7 @@ public class TestExecutorC extends TestC { @Test void testExecutorC() { - Executor.executeC(addIntPtrs, "addIntPtrs", addIntArgs); + Executor.executeC(addInts, "addInts", addIntArgs); Executor.executeC(saxpy, "saxpy", saxpyArgs); assertEquals(5, ((IntArg) addIntArgs[2]).asIntArray()[0]); @@ -16,7 +16,7 @@ void testExecutorC() { String compiler = "gcc"; - Executor.executeC(addIntPtrs, "addIntPtrs", compiler, addIntArgs); + Executor.executeC(addInts, "addInts", compiler, addIntArgs); Executor.executeC(saxpy, "saxpy", compiler, saxpyArgs); assertEquals(5, ((IntArg) addIntArgs[2]).asIntArray()[0]); @@ -28,7 +28,7 @@ void testExecutorC() { o2.insert("-Wextra"); o2.insert("-pedantic"); - Executor.executeC(addIntPtrs, "addIntPtrs", compiler, o1, addIntArgs); + Executor.executeC(addInts, "addInts", compiler, o1, addIntArgs); Executor.executeC(saxpy, "saxpy", compiler, o2, saxpyArgs); assertEquals(5, ((IntArg) addIntArgs[2]).asIntArray()[0]); From 452e0c8cefe2a30f7f6d4f159ea7c7ba797775e9 Mon Sep 17 00:00:00 2001 From: Lukas Date: Fri, 28 Feb 2020 23:49:05 +0100 Subject: [PATCH 3/4] Fixed CMakeLists JavaTests --- test/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1971ca7..c2d51f6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -51,12 +51,16 @@ include(Catch) catch_discover_tests(tests) set(JAVA_TEST_FILES + "test/java/yacx/TestArrayArg.java" "test/java/yacx/TestBooleanArg.java" + "test/java/yacx/TestByteArg.java" + "test/java/yacx/TestCProgram.java" "test/java/yacx/TestDevice.java" "test/java/yacx/TestDoubleArg.java" "test/java/yacx/TestExecuteFilter.java" "test/java/yacx/TestExecuteSaxpy.java" "test/java/yacx/TestExecutor.java" + "test/java/yacx/TestExecutorC.java" "test/java/yacx/TestFloatArg.java" "test/java/yacx/TestHeaders.java" "test/java/yacx/TestIntArg.java" @@ -64,6 +68,7 @@ set(JAVA_TEST_FILES "test/java/yacx/TestKernel.java" "test/java/yacx/TestLongArg.java" "test/java/yacx/TestOptions.java" + "test/java/yacx/TestPaddingArg.java" "test/java/yacx/TestProgram.java" "test/java/yacx/TestShortArg.java" "test/java/yacx/TestUtils.java") @@ -91,7 +96,7 @@ if(JNI_ENABLED) OUTPUT "${PROJECT_BINARY_DIR}/java/bin/${_class_file}" COMMAND ${Java_JAVAC_EXECUTABLE} ${CMAKE_JAVA_COMPILE_FLAGS} - -sourcepath "${PROJECT_SOURCE_DIR}/src/java:${PROJECT_SOURCE_DIR}/test/java" + -sourcepath "${PROJECT_SOURCE_DIR}/src/main/java:${PROJECT_SOURCE_DIR}/test/java" -d "${PROJECT_BINARY_DIR}/java/bin" -cp "${PROJECT_BINARY_DIR}/java/bin/src/junit-platform-console-standalone-1.5.2.jar" "${PROJECT_SOURCE_DIR}/test/java/yacx/${_java_file}" From 0dc267b8b8c6daafb63582789afdd13d8b29e1a1 Mon Sep 17 00:00:00 2001 From: Lukas Date: Sat, 29 Feb 2020 22:29:15 +0100 Subject: [PATCH 4/4] Rerun CI --- include/yacx/cexecutor/LibaryLoader.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/yacx/cexecutor/LibaryLoader.hpp b/include/yacx/cexecutor/LibaryLoader.hpp index 0e34893..900d7c7 100644 --- a/include/yacx/cexecutor/LibaryLoader.hpp +++ b/include/yacx/cexecutor/LibaryLoader.hpp @@ -19,7 +19,7 @@ struct opfn { //! \param opSymbolName name of the opfn-struct containg the operation, wich should be loaded void load_op(struct dynop *dest, std::string filename, std::string opSymbolName); //! unloads the libary and cleans the struct -//! \param op +//! \param op struct to store pointer to loaded operation void unload_op(struct dynop *op); } // namespace detail -} // namespace yacx \ No newline at end of file +} // namespace yacx