diff --git a/CMakeCommon/FindOpenCL.cmake b/CMakeCommon/FindOpenCL.cmake new file mode 100755 index 0000000..d6533f9 --- /dev/null +++ b/CMakeCommon/FindOpenCL.cmake @@ -0,0 +1,147 @@ +# Taken from CMake Version 3.2.1, modified to work on older versions +#.rst: +# FindOpenCL +# ---------- +# +# Try to find OpenCL +# +# Once done this will define:: +# +# OpenCL_FOUND - True if OpenCL was found +# OpenCL_INCLUDE_DIRS - include directories for OpenCL +# OpenCL_LIBRARIES - link against this library to use OpenCL +# OpenCL_VERSION_STRING - Highest supported OpenCL version (eg. 1.2) +# OpenCL_VERSION_MAJOR - The major version of the OpenCL implementation +# OpenCL_VERSION_MINOR - The minor version of the OpenCL implementation +# +# The module will also define two cache variables:: +# +# OpenCL_INCLUDE_DIR - the OpenCL include directory +# OpenCL_LIBRARY - the path to the OpenCL library +# + +#============================================================================= +# Copyright 2014 Matthaeus G. Chajdas +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +function(_FIND_OPENCL_VERSION) + include(CheckSymbolExists) + include(CMakePushCheckState) + set(CMAKE_REQUIRED_QUIET ${OpenCL_FIND_QUIETLY}) + + CMAKE_PUSH_CHECK_STATE() + foreach(VERSION "2_0" "1_2" "1_1" "1_0") + set(CMAKE_REQUIRED_INCLUDES "${OpenCL_INCLUDE_DIR}") + + if(APPLE) + CHECK_SYMBOL_EXISTS( + CL_VERSION_${VERSION} + "${OpenCL_INCLUDE_DIR}/OpenCL/cl.h" + OPENCL_VERSION_${VERSION}) + else() + CHECK_SYMBOL_EXISTS( + CL_VERSION_${VERSION} + "${OpenCL_INCLUDE_DIR}/CL/cl.h" + OPENCL_VERSION_${VERSION}) + endif() + + if(OPENCL_VERSION_${VERSION}) + string(REPLACE "_" "." VERSION "${VERSION}") + set(OpenCL_VERSION_STRING ${VERSION} PARENT_SCOPE) + string(REGEX MATCHALL "[0-9]+" version_components "${VERSION}") + list(GET version_components 0 major_version) + list(GET version_components 1 minor_version) + set(OpenCL_VERSION_MAJOR ${major_version} PARENT_SCOPE) + set(OpenCL_VERSION_MINOR ${minor_version} PARENT_SCOPE) + break() + endif() + endforeach() + CMAKE_POP_CHECK_STATE() +endfunction() + +find_path(OpenCL_INCLUDE_DIR + NAMES + CL/cl.h OpenCL/cl.h + PATHS + ENV "PROGRAMFILES(X86)" + ENV AMDAPPSDKROOT + ENV INTELOCLSDKROOT + ENV NVSDKCOMPUTE_ROOT + ENV CUDA_PATH + ENV ATISTREAMSDKROOT + PATH_SUFFIXES + include + OpenCL/common/inc + "AMD APP/include") + +_FIND_OPENCL_VERSION() + +if(WIN32) + if(CMAKE_SIZEOF_VOID_P EQUAL 4) + find_library(OpenCL_LIBRARY + NAMES OpenCL + PATHS + ENV "PROGRAMFILES(X86)" + ENV AMDAPPSDKROOT + ENV INTELOCLSDKROOT + ENV CUDA_PATH + ENV NVSDKCOMPUTE_ROOT + ENV ATISTREAMSDKROOT + PATH_SUFFIXES + "AMD APP/lib/x86" + lib/x86 + lib/Win32 + OpenCL/common/lib/Win32) + elseif(CMAKE_SIZEOF_VOID_P EQUAL 8) + find_library(OpenCL_LIBRARY + NAMES OpenCL + PATHS + ENV "PROGRAMFILES(X86)" + ENV AMDAPPSDKROOT + ENV INTELOCLSDKROOT + ENV CUDA_PATH + ENV NVSDKCOMPUTE_ROOT + ENV ATISTREAMSDKROOT + PATH_SUFFIXES + "AMD APP/lib/x86_64" + lib/x86_64 + lib/x64 + OpenCL/common/lib/x64) + endif() +else() + find_library(OpenCL_LIBRARY + NAMES OpenCL) +endif() + +set(OpenCL_LIBRARIES ${OpenCL_LIBRARY}) +set(OpenCL_INCLUDE_DIRS ${OpenCL_INCLUDE_DIR}) + + +#find_package_handle_standard_args not available in older CMake versions... +#include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +#find_package_handle_standard_args( +# OpenCL +# FOUND_VAR OpenCL_FOUND +# REQUIRED_VARS OpenCL_LIBRARY OpenCL_INCLUDE_DIR +# VERSION_VAR OpenCL_VERSION_STRING) + +#mark_as_advanced( +# OpenCL_INCLUDE_DIR +# OpenCL_LIBRARY) + +# This replaces FindPackageHandleStandardArgs.cmake, which is not available in older +# CMake versions +if( OpenCL_LIBRARIES AND OpenCL_INCLUDE_DIRS ) + set(OpenCL_FOUND 1) +else() + set(OpenCL_FOUND 0) +endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index f89aaf8..837e52c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,13 @@ if(POLICY CMP0053) endif(POLICY CMP0053) +include(CMakeCommon/FindOpenCL.cmake) +IF(NOT OpenCL_FOUND) + MESSAGE( STATUS "OpenCL is not there, will build without MTAPI OpenCL Plugin." ) +ENDIF() + + + if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release @@ -117,8 +124,26 @@ else() endif() message(" (set with command line option -DUSE_EXCEPTIONS=ON/OFF)") +# these are the test executables, we expect to be generated. +set(EXPECTED_EMBB_TEST_EXECUTABLES "embb_algorithms_cpp_test" + "embb_base_c_test" + "embb_base_cpp_test" + "embb_containers_cpp_test" + "embb_dataflow_cpp_test" + "embb_mtapi_c_test" + "embb_mtapi_cpp_test" + "embb_mtapi_network_c_test" + "embb_tasks_cpp_test" + ) + +# if opencl is there, we also expect the mtapi opencl test to be generated +if(OpenCL_FOUND) + list(APPEND EXPECTED_EMBB_TEST_EXECUTABLES "embb_mtapi_opencl_c_test") +endif() + + ## Copy test execution script to local binaries folder -# + if (DEFINED CYGWIN) set(test_script_in run_tests_cygwin.sh) set(test_script_out run_tests.sh) @@ -129,9 +154,7 @@ else() set(test_script_in run_tests_windows.bat) set(test_script_out run_tests.bat) endif() -execute_process( - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/scripts/${test_script_in} binaries/${test_script_out} - ) +CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/scripts/${test_script_in}.cmake binaries/${test_script_out} ) ## Test and Partest build # @@ -150,7 +173,9 @@ add_subdirectory(base_c) add_subdirectory(base_cpp) add_subdirectory(mtapi_c) add_subdirectory(mtapi_network_c) -add_subdirectory(mtapi_opencl_c) +if(OpenCL_FOUND) + add_subdirectory(mtapi_opencl_c) +endif() add_subdirectory(tasks_cpp) add_subdirectory(mtapi_cpp) add_subdirectory(containers_cpp) diff --git a/containers_cpp/test/queue_test-inl.h b/containers_cpp/test/queue_test-inl.h index 39d350f..3e63930 100644 --- a/containers_cpp/test/queue_test-inl.h +++ b/containers_cpp/test/queue_test-inl.h @@ -290,7 +290,7 @@ QueueTestSingleThreadEnqueueDequeue_ThreadMethod() { } // Oversized amount should not be larger than the original capacity PT_ASSERT_LT(oversized_count, 2 * n_queue_size); - + // Dequeue the expected amount of elements for (int i = 0; i != n_queue_size; ++i) { element_t dequ(0, -1); diff --git a/dataflow_cpp/test/dataflow_cpp_test_simple.cc b/dataflow_cpp/test/dataflow_cpp_test_simple.cc index bf5b386..c2df7f7 100644 --- a/dataflow_cpp/test/dataflow_cpp_test_simple.cc +++ b/dataflow_cpp/test/dataflow_cpp_test_simple.cc @@ -36,6 +36,9 @@ #include +#define NUM_SLICES 8 +#define TEST_COUNT 12 + typedef embb::dataflow::Network<8> MyNetwork; typedef MyNetwork::ConstantSource< int > MyConstantSource; typedef MyNetwork::Source< int > MySource; @@ -49,8 +52,6 @@ typedef MyNetwork::Sink< int > MySink; typedef MyNetwork::Switch< int > MySwitch; typedef MyNetwork::Select< int > MySelect; -#define TEST_COUNT 12 - embb::base::Atomic source_counter; int source_array[TEST_COUNT]; @@ -142,8 +143,24 @@ SimpleTest::SimpleTest() { CreateUnit("dataflow_cpp simple test").Add(&SimpleTest::TestBasic, this); } +#define MTAPI_DOMAIN_ID 1 +#define MTAPI_NODE_ID 1 + void SimpleTest::TestBasic() { - embb::tasks::Node::Initialize(1, 1); + // All available cores + embb::base::CoreSet core_set(true); + int num_cores = core_set.Count(); + embb::tasks::Node::Initialize( + MTAPI_DOMAIN_ID, + MTAPI_NODE_ID, + core_set, + 1024, // max tasks (default: 1024) + 128, // max groups (default: 128) + // Currently needs to be initialized + // with (max_queues + 1), see defect embb449 + num_cores + 1, // max queues (default: 16) + 1024, // queue capacity (default: 1024) + 4); // num priorities (default: 4) for (int ii = 0; ii < 10000; ii++) { ArraySink asink; @@ -163,6 +180,7 @@ void SimpleTest::TestBasic() { filter_array[kk] = -1; mult_array[kk] = -1; } + source_counter = 0; pred_counter = 0; mult_counter = 0; @@ -189,7 +207,11 @@ void SimpleTest::TestBasic() { network.AddSource(constant); network.AddSource(source); - network(); + try { + network(); + } catch (embb::base::ErrorException & e) { + PT_ASSERT_MSG(false, e.What()); + } PT_EXPECT(asink.Check()); } @@ -198,3 +220,4 @@ void SimpleTest::TestBasic() { PT_EXPECT(embb_get_bytes_allocated() == 0); } + diff --git a/doc/examples/CMakeLists.txt b/doc/examples/CMakeLists.txt index 8f49812..d68a8a3 100644 --- a/doc/examples/CMakeLists.txt +++ b/doc/examples/CMakeLists.txt @@ -2,6 +2,7 @@ project (project_embb_tutorials) file(GLOB_RECURSE EXAMPLES_SOURCES "*.cc" "*.h") + include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/ ${CMAKE_CURRENT_BINARY_DIR}/ @@ -12,7 +13,6 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_c/include ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_c/src ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_network_c/include - ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_opencl_c/include ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_cpp/include ${CMAKE_CURRENT_SOURCE_DIR}/../../tasks_cpp/include ${CMAKE_CURRENT_BINARY_DIR}/../../tasks_cpp/include @@ -21,6 +21,21 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../../dataflow_cpp/include ) +if(OpenCL_FOUND) + # used in source code, to include opencl code + add_definitions(-DEMBB_WITH_OPENCL) + # add opencl includes + include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_opencl_c/include + ) + # later used, to link opencl to target... + set (EMBB_MTAPI_OPENCL_C_CONDITIONAL "embb_mtapi_opencl_c") +else() + # remove opencl examples from sources (should not be build) + file(GLOB_RECURSE EXAMPLES_SOURCES_OPENCL_TO_REMOVE "*opencl*" ) + list(REMOVE_ITEM EXAMPLES_SOURCES ${EXAMPLES_SOURCES_OPENCL_TO_REMOVE}) +endif() + if(CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_CXX_FLAGS "-std=c++11") set (EXTRA_LIBS dl) @@ -32,7 +47,7 @@ ENDIF() add_executable(examples ${EXAMPLES_SOURCES}) target_link_libraries(examples embb_dataflow_cpp embb_algorithms_cpp embb_tasks_cpp embb_mtapi_cpp - embb_mtapi_network_c embb_mtapi_opencl_c embb_mtapi_c + embb_mtapi_network_c ${EMBB_MTAPI_OPENCL_C_CONDITIONAL} embb_mtapi_c embb_base_cpp embb_base_c embb_containers_cpp ${EXTRA_LIBS} ${compiler_libs}) CopyBin(BIN examples DEST ${local_install_dir}) diff --git a/doc/examples/main.cc b/doc/examples/main.cc index 54414bf..7888d4b 100644 --- a/doc/examples/main.cc +++ b/doc/examples/main.cc @@ -30,7 +30,9 @@ void RunMTAPI_C(); void RunMTAPI_C_Plugin(); void RunMTAPI_C_Network(); +#ifdef EMBB_WITH_OPENCL void RunMTAPI_C_OpenCL(); +#endif void RunMTAPI_CPP(); void RunTasks(); void RunDataflowLinear(); @@ -66,9 +68,11 @@ int main() { RunMTAPI_C_Network(); std::cout << "RunMTAPI_C_Network() ... done" << std::endl; +#ifdef EMBB_WITH_OPENCL std::cout << "RunMTAPI_C_OpenCL() ..." << std::endl; RunMTAPI_C_OpenCL(); std::cout << "RunMTAPI_C_OpenCL() ... done" << std::endl; +#endif std::cout << "RunMTAPI_CPP() ..." << std::endl; RunMTAPI_CPP(); diff --git a/mtapi_opencl_c/src/embb_mtapi_opencl.c b/mtapi_opencl_c/src/embb_mtapi_opencl.c index b503b76..2be0693 100644 --- a/mtapi_opencl_c/src/embb_mtapi_opencl.c +++ b/mtapi_opencl_c/src/embb_mtapi_opencl.c @@ -46,8 +46,8 @@ struct embb_mtapi_opencl_plugin_struct { cl_device_id device_id; cl_context context; cl_command_queue command_queue; - cl_uint work_group_size; - cl_uint work_item_sizes[3]; + size_t work_group_size; + size_t work_item_sizes[3]; }; typedef struct embb_mtapi_opencl_plugin_struct embb_mtapi_opencl_plugin_t; @@ -270,12 +270,13 @@ void mtapi_opencl_plugin_initialize( NULL, NULL, &err); } if (CL_SUCCESS == err) { + size_t work_group_size; err = clGetDeviceInfo(plugin->device_id, CL_DEVICE_MAX_WORK_GROUP_SIZE, - sizeof(cl_uint), &plugin->work_group_size, NULL); + sizeof(size_t), &plugin->work_group_size, NULL); } if (CL_SUCCESS == err) { err = clGetDeviceInfo(plugin->device_id, CL_DEVICE_MAX_WORK_ITEM_SIZES, - 3 * sizeof(cl_uint), &plugin->work_item_sizes[0], NULL); + 3 * sizeof(size_t), &plugin->work_item_sizes[0], NULL); } if (CL_SUCCESS == err) { plugin->command_queue = clCreateCommandQueue(plugin->context, diff --git a/scripts/run_tests_cygwin.sh b/scripts/run_tests_cygwin.sh.cmake similarity index 92% rename from scripts/run_tests_cygwin.sh rename to scripts/run_tests_cygwin.sh.cmake index 43ae62d..2fce866 100755 --- a/scripts/run_tests_cygwin.sh +++ b/scripts/run_tests_cygwin.sh.cmake @@ -27,6 +27,7 @@ # Needs to be located in the folder containing the tests!! # Is copied automatically there when generating build files with cmake. +EMBB_TEST_EXECUTABLES="@EXPECTED_EMBB_TEST_EXECUTABLES@" SCRIPT_LOCATION="$0" # case we have symlinks... @@ -36,10 +37,6 @@ done DIR=`dirname "$SCRIPT_LOCATION"` -TESTS="embb_base_c_test embb_base_cpp_test embb_mtapi_c_test \ - embb_mtapi_cpp_test embb_tasks_cpp_test embb_algorithms_cpp_test \ - embb_containers_cpp_test embb_dataflow_cpp_test" - -for TEST in $TESTS; do +for TEST in $(echo $EMBB_TEST_EXECUTABLES | tr ";" " "); do "$DIR/$TEST".exe; done diff --git a/scripts/run_tests_unix.sh b/scripts/run_tests_unix.sh.cmake similarity index 91% rename from scripts/run_tests_unix.sh rename to scripts/run_tests_unix.sh.cmake index a39ede6..b668b9b 100755 --- a/scripts/run_tests_unix.sh +++ b/scripts/run_tests_unix.sh.cmake @@ -27,6 +27,7 @@ # Needs to be located in the folder containing the tests!! # Is copied automatically there when generating build files with cmake. +EMBB_TEST_EXECUTABLES="@EXPECTED_EMBB_TEST_EXECUTABLES@" SCRIPT_LOCATION="$0" # case we have symlinks... @@ -36,10 +37,6 @@ done DIR=`dirname "$SCRIPT_LOCATION"` -TESTS="embb_base_c_test embb_base_cpp_test embb_mtapi_c_test \ - embb_mtapi_cpp_test embb_tasks_cpp_test embb_algorithms_cpp_test \ - embb_containers_cpp_test embb_dataflow_cpp_test" - -for TEST in $TESTS; do +for TEST in $(echo $EMBB_TEST_EXECUTABLES | tr ";" " "); do $DIR/$TEST; done diff --git a/scripts/run_tests_windows.bat b/scripts/run_tests_windows.bat.cmake similarity index 66% rename from scripts/run_tests_windows.bat rename to scripts/run_tests_windows.bat.cmake index 1621f08..c3d4a44 100644 --- a/scripts/run_tests_windows.bat +++ b/scripts/run_tests_windows.bat.cmake @@ -28,29 +28,28 @@ setlocal EnableDelayedExpansion SET NUM_ERRORS=0 SET DIR=%~dp0 -"%DIR:~0,-1%\embb_base_c_test.exe" -if not !ERRORLEVEL! ==0 set /a NUM_ERRORS=!NUM_ERRORS!+1 -echo. -"%DIR:~0,-1%\embb_base_cpp_test.exe" -if not !ERRORLEVEL! ==0 set /a NUM_ERRORS=!NUM_ERRORS!+1 -echo. -"%DIR:~0,-1%\embb_mtapi_c_test.exe" -if not !ERRORLEVEL! ==0 set /a NUM_ERRORS=!NUM_ERRORS!+1 -echo. -"%DIR:~0,-1%\embb_mtapi_cpp_test.exe" -if not !ERRORLEVEL! ==0 set /a NUM_ERRORS=!NUM_ERRORS!+1 -echo. -"%DIR:~0,-1%\embb_tasks_cpp_test.exe" -if not !ERRORLEVEL! ==0 set /a NUM_ERRORS=!NUM_ERRORS!+1 -echo. -"%DIR:~0,-1%\embb_algorithms_cpp_test.exe" -if not !ERRORLEVEL! ==0 set /a NUM_ERRORS=!NUM_ERRORS!+1 -echo. -"%DIR:~0,-1%\embb_containers_cpp_test.exe" -if not !ERRORLEVEL! ==0 set /a NUM_ERRORS=!NUM_ERRORS!+1 -echo. -"%DIR:~0,-1%\embb_dataflow_cpp_test.exe" +SET EMBB_EXECUTABLES=@EXPECTED_EMBB_TEST_EXECUTABLES@ + +call :parse "%EMBB_EXECUTABLES%" +goto :end + +:parse +set list=%1 +set list=%list:"=% +FOR /f "tokens=1* delims=;" %%a IN ("%list%") DO ( + if not "%%a" == "" call :sub %%a + if not "%%b" == "" call :parse "%%b" +) +exit /b + +:sub +call "%DIR:~0,-1%\%1.exe" if not !ERRORLEVEL! ==0 set /a NUM_ERRORS=!NUM_ERRORS!+1 +exit /b + + +:end + if not !NUM_ERRORS! ==0 ( echo. SET ERRORLEVEL=1 diff --git a/tasks_cpp/src/queue.cc b/tasks_cpp/src/queue.cc index 04e94b8..098f379 100644 --- a/tasks_cpp/src/queue.cc +++ b/tasks_cpp/src/queue.cc @@ -54,7 +54,18 @@ Queue::Queue(mtapi_uint_t priority, bool ordered) { mtapi_job_hndl_t job = mtapi_job_get(TASKS_CPP_JOB, domain_id, &status); assert(MTAPI_SUCCESS == status); handle_ = mtapi_queue_create(MTAPI_QUEUE_ID_NONE, job, &attr, &status); - if (MTAPI_SUCCESS != status) { + // Handle MTAPI error status in appropriate exceptions + if (status == MTAPI_SUCCESS) { + return; + } else if (status == MTAPI_ERR_QUEUE_LIMIT) { + EMBB_THROW(embb::base::ErrorException, + "mtapi::Queue could not be constructed, " + "maximum number of queues exceeded"); + } else if (status == MTAPI_ERR_JOB_INVALID) { + EMBB_THROW(embb::base::ErrorException, + "mtapi::Queue could not be constructed, " + "invalid job"); + } else { EMBB_THROW(embb::base::ErrorException, "mtapi::Queue could not be constructed"); }