diff --git a/CMakeLists.txt b/CMakeLists.txt index d2530cc7992bbdba69149f6d619e3fb5e80ed9b0..a6cdbe933661ea578da1772f4e08bf9d512caa0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,6 @@ endif() set(BOOST_INCLUDE ${Boost_INCLUDE_DIR} CACHE PATH "Include directory for BOOST") set(HDF5_ROOT CACHE PATH "HDF5 root path") set(SE_CLASS1 CACHE BOOL "Activate compilation with SE_CLASS1") -set(SE_CLASS2 CACHE BOOL "Activate compilation with SE_CLASS2") set(SE_CLASS3 CACHE BOOL "Activate compilation with SE_CLASS3") set(ENV{HDF5_ROOT} ${HDF5_ROOT}) set(OPENFPM_PDATA_DIR CACHE PATH "OpenFPM_pdata dirs") @@ -45,7 +44,10 @@ if(ENABLE_GPU) elseif ( CUDA_VERSION_MAJOR EQUAL 10 AND CUDA_VERSION_MINOR EQUAL 2 ) message("CUDA is compatible") set(WARNING_SUPPRESSION_AND_OPTION_NVCC -Xcudafe "--display_error_number --diag_suppress=2977 --diag_suppress=2976 --diag_suppress=2979 --diag_suppress=186" --expt-extended-lambda) - else() + elseif ( CUDA_VERSION_MAJOR EQUAL 11 AND CUDA_VERSION_MINOR EQUAL 0 ) + message("CUDA is compatible 11.0") + set(WARNING_SUPPRESSION_AND_OPTION_NVCC -Xcudafe "--display_error_number --diag_suppress=3059 --diag_suppress=3058 --diag_suppress=3057 --diag_suppress=3056 --diag_suppress=611 --diag_suppress=186" --expt-extended-lambda) + else() message(FATAL_ERROR "CUDA is incompatible, version 9.2 10.1 and 10.2 is only supported") endif() endif() @@ -68,10 +70,6 @@ if(SE_CLASS1) set(DEFINE_SE_CLASS1 "#define SE_CLASS1") endif() -if(SE_CLASS2) - set(DEFINE_SE_CLASS2 "#define SE_CLASS2") -endif() - if(SE_CLASS3) set(DEFINE_SE_CLASS3 "#define SE_CLASS3") endif() diff --git a/configure b/configure index 58a970ce6f68fb305ca1699444b61d7e9cd02c7d..8b284b8e6a6ff5af329ad0a1da39ed79cad353c9 100755 --- a/configure +++ b/configure @@ -104,7 +104,6 @@ enable_test_performance enable_test_coverage with_parmetis enable_se_class1 -enable_se_class2 enable_se_class3 with_action_on_error with_boost @@ -220,9 +219,6 @@ do se_class1) conf_options="$conf_options -DSE_CLASS1=ON" ;; - se_class2) - conf_options="$conf_options -DSE_CLASS2=ON" - ;; se_class3) conf_options="$conf_options -DSE_CLASS3=ON" ;; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 87dafed2448824d29b617e398601b3c855f883a6..49d873c2ec77003be5667d7d4bb2d41bcff39a4c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,7 +9,6 @@ add_executable(io main.cpp ../../openfpm_vcluster/src/VCluster/VCluster.cpp ../../openfpm_devices/src/memory/CudaMemory.cu ../../openfpm_devices/src/memory/HeapMemory.cpp - ../../openfpm_devices/src/Memleak_check.cpp ../../openfpm_devices/src/memory/PtrMemory.cpp) if ( CMAKE_COMPILER_IS_GNUCC ) @@ -106,6 +105,12 @@ install(FILES HDF5_wr/HDF5_wr.hpp HDF5_wr/HDF5_reader_vd.hpp DESTINATION openfpm_io/include/HDF5_wr) +install(FILES RawReader/InitGridWithPixel.hpp + DESTINATION openfpm_io/include/RawReader/) + +install(FILES util/PathsAndFiles.hpp + DESTINATION openfpm_io/include/util) + install(FILES Plot/GoogleChart.hpp Plot/util.hpp DESTINATION openfpm_io/include/Plot ) diff --git a/src/HDF5_wr/HDF5_writer_gd.hpp b/src/HDF5_wr/HDF5_writer_gd.hpp index 8a1b98e78d433c6975940e2373287c893e0f30c1..f41de0fec8f6c888a78e2f2118c7f1b0e6048576 100644 --- a/src/HDF5_wr/HDF5_writer_gd.hpp +++ b/src/HDF5_wr/HDF5_writer_gd.hpp @@ -173,6 +173,9 @@ public: H5Sclose(file_dataspace_id_2); H5Pclose(plist_id); H5Fclose(file); + + mem.decRef(); + delete &mem; } }; diff --git a/src/HDF5_wr/HDF5_writer_vd.hpp b/src/HDF5_wr/HDF5_writer_vd.hpp index 70015ba6f6acff2f6aab85634032bfff6e78d2c2..f6bd869a75ee2bb1897f6cb9ab982ca85ab50a9e 100644 --- a/src/HDF5_wr/HDF5_writer_vd.hpp +++ b/src/HDF5_wr/HDF5_writer_vd.hpp @@ -156,6 +156,8 @@ public: H5Sclose(mem_dataspace_id); H5Pclose(plist_id); H5Fclose(file); + mem.decRef(); + delete &mem; } /*! \brief Return the equivalent HDF5 type for T diff --git a/src/RawReader/InitGridWithPixel.hpp b/src/RawReader/InitGridWithPixel.hpp new file mode 100644 index 0000000000000000000000000000000000000000..01e23eca25bbc21394d28f9271d57de82afee39e --- /dev/null +++ b/src/RawReader/InitGridWithPixel.hpp @@ -0,0 +1,165 @@ +// +// Created by jstark on 2019-11-07. +// +/** + * @file InitGridWithPixel.hpp + * + * @brief Header file containing functions for loading pixel values from 2D image or 3D image stack (volume) stored + * in a binary file onto an openFPM grid. + * + * @details Can be run in parallel. + * + * @author Justina Stark + * @date November 2019 - August 2020 + */ +#ifndef IMAGE_BASED_RECONSTRUCTION_GETINITIALGRID_HPP +#define IMAGE_BASED_RECONSTRUCTION_GETINITIALGRID_HPP + +#include <iostream> +#include <typeinfo> +#include <cmath> + +#include "Vector/vector_dist.hpp" +#include "Grid/grid_dist_id.hpp" +#include "data_type/aggregate.hpp" +#include "Decomposition/CartDecomposition.hpp" + +#include "level_set/redistancing_Sussman/HelpFunctionsForGrid.hpp" +typedef signed char BYTE; +/**@brief Read the number of pixels per dimension from a csv-file in order to create a grid with the same size. + * + * @param path_to_file Std::string containing the path to the csv file that holds the image/volume size in + * #pixels per dimension. + * @return Std::vector containing the count of pixels for each dimension as it was read from the csv file. + */ +std::vector<size_t> get_size(const std::string & path_to_file) +{ + std::vector<size_t> stack_dimst_1d; + // stream input csv file and error check + std::ifstream file(path_to_file); + if (!file) + { + std::cout << "Error opening file" << std::endl; + exit (EXIT_FAILURE); + } + + // get its size + std::streampos fileSize; + file.seekg(0, std::ios::end); + fileSize = file.tellg(); + file.seekg(0, std::ios::beg); + + // reserve capacity + stack_dimst_1d.reserve(fileSize); + + std::string field; + while ( getline(file, field) ) // 1 field per axis + { + std::istringstream iss(field); + size_t val; + iss >> val; + stack_dimst_1d.push_back(val); // add the #pixels for current axis to the array + } + + // reverse order to compensate reverse reading + std::reverse(std::begin(stack_dimst_1d), std::end(stack_dimst_1d)); + + return stack_dimst_1d; +} + + +/**@brief Converts the pixel values stored in a binary file into doubles and loads them onto an OpenFPM grid. + * + * @tparam Phi_0 Index of property in which pixel value should be stored. + * @tparam grid_type Type of OpenFPM grid. + * @param grid Grid of type grid_type, on which image / image-stack should be loaded. + * @param file_name Std::string containing the path + name of the binary file that stores the pixel values. + * @param stack_dims Size_t variable that contains the dimensionality of the image / image stack. Can be given + * manually or loaded from a csv file before (see: #get_size()) + */ +template <size_t Phi_0, typename grid_type> +void load_pixel_onto_grid(grid_type & grid, std::string file_name, std::vector <size_t> & stack_dims) +{ + constexpr size_t x = 0; + constexpr size_t y = 1; + constexpr size_t z = 2; + + std::ifstream file_stream (file_name, std::ifstream::binary); + + auto & v_cl = create_vcluster(); + if (v_cl.rank() == 0) + { + for (size_t d = 0; d < grid_type::dims; d++) + { + std::cout << "# grid points in dimension " << d << " = " << grid.size(d) << std::endl; + } + } + + // initialize complete grid including ghost layer with -1 + init_grid_and_ghost<Phi_0>(grid, -1.0); + + // assign pixel values to domain. For each pixel get factor_refinement number of grid points with corresponding value + auto dom = grid.getDomainIterator(); + std::vector<BYTE> pixel_line; // one x-line of the image stack which will be read + + size_t sz_img[grid_type::dims]; + for (size_t d = 0; d < grid_type::dims; d++) + { + sz_img[d] = stack_dims[d]; + } + grid_sm<grid_type::dims,void> ginfo_image(sz_img); // in order to get the image related key later on + + double refinement[grid_type::dims]; + for (size_t d = 0; d < grid_type::dims; d++) + { + refinement[d] = (double) grid.size(d) / (double)stack_dims[d]; // get the factor, by which the grid resolution differs from the image stack resolution + if (v_cl.rank() == 0) std::cout << "effective refinement in dimension " << d << " = " << refinement[d] << std::endl; + } + + while(dom.isNext()) + { + auto key = dom.get(); + auto gkey = grid.getGKey(key); + + // get l as the length of one x-line of the original image stack for the specific patch on the processor + auto & gbox = grid.getLocalGridsInfo(); + auto & DomBox = gbox.get(key.getSub()).Dbox; + int l = (size_t) std::round((DomBox.getHigh(0) - DomBox.getLow(0) + 1) / refinement[x]); + + // in case that the grid has a different resolution than the underlying image stack: + // create a key which is used to get the offset for the file reading + // the indices in this key are corrected by the refinement factor + for (size_t d = 1; d < grid_type::dims; d++) + { + gkey.set_d(d, std::round(gkey.get(d) / refinement[d])); + } + + // the offset matches the pixel from the image stack to the corresponding current position of the iterator + // in the grid + size_t offset = ginfo_image.LinId(gkey); + file_stream.seekg(offset); // jump to the correct position in the file + + // prepare space for the pixel values of one x-line in the original image stack + pixel_line.resize(l); + // stream the file and fill pixel values into pixel_line + file_stream.read((char*) & pixel_line[0], l); + + // run over a whole grid-line in x and assign pixel values from pixel_line to grid nodes + // if the grid is finer in x as the image stack, the same pixel value from pixel_line is + // assigned refinement[x] times + for (size_t i = 0; i < l * refinement[x]; i++) + { + auto key = dom.get(); + grid.template get<Phi_0>(key) = (double) pixel_line[(size_t)floor(i / refinement[x])]; + ++dom; + } + // now one grid line in x is finished and the iterator dom has advanced accordingly s.t. next loop continues + // with next line, meaning that y increased by 1 (or z respectivley, when y = ymax + 1) + } + + grid.template ghost_get<Phi_0>(); +} + + + +#endif //IMAGE_BASED_RECONSTRUCTION_GETINITIALGRID_HPP diff --git a/src/config/config_cmake.h.in b/src/config/config_cmake.h.in index 02de32fc4b93d79ac946dbb08127a707b6f7de44..85840022fcec2c75463a60a05aa6c09b76ea448e 100644 --- a/src/config/config_cmake.h.in +++ b/src/config/config_cmake.h.in @@ -140,9 +140,6 @@ ${DEFINE_PERFORMANCE_TEST} /* Security enhancement class 1 */ ${DEFINE_SE_CLASS1} -/* Security enhancement class 2 */ -${DEFINE_SE_CLASS2} - /* Security enhancement class 3 */ ${DEFINE_SE_CLASS3} diff --git a/src/util/PathsAndFiles.hpp b/src/util/PathsAndFiles.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e5cd27e52a1ef26b3c5bb9aa249438b4a5a8c1c8 --- /dev/null +++ b/src/util/PathsAndFiles.hpp @@ -0,0 +1,122 @@ +// +// Created by jstark on 2019-12-03. +// +/** + * @file PathsAndFiles.hpp + * + * @brief Header file containing functions for creating files and folders. + * + * @author Justina Stark + * @date December 2019 + */ + +#ifndef FILES_READ_AND_WRITE_PATHSANDFILES_HPP +#define FILES_READ_AND_WRITE_PATHSANDFILES_HPP +#include <unistd.h> +#include <iostream> +#include <fstream> +#include <boost/filesystem.hpp> +/**@brief Gets the current working directory and returns path as string. + * + * @return Std::string of path to current working directory. + */ +std::string get_cwd() +{ + char *cwd = nullptr; + size_t size; + cwd = getcwd(cwd, size); + + // convert current directory to string + std::string s_cwd; + s_cwd = cwd; + + // std::cout << "The current working directory is: " << dir << std::endl; + return s_cwd; +} +/**@brief Checks if a file already exists. + * + * @param path Std::string with path of file for which existence should be checked. + * @return True, if file exists, false if not. + */ +bool check_if_file_exists(std::string path) +{ + try + { + // Create a filesystem::path object from given path string + boost::filesystem::path pathObj(path); + if (boost::filesystem::exists(pathObj) && boost::filesystem::is_regular_file(pathObj)) + { + return true; +// BOOST_LOG_TRIVIAL(info) << path << " -> File exists."; + } + + } + catch (boost::filesystem::filesystem_error & e) + { + std::cerr << e.what() << std::endl; +// BOOST_LOG_TRIVIAL(error) << "Error when checking existence of file ( " << path << " ): " << e.what(); + } + return false; +} +/**@brief Creates a file if not already existent. + * + * @param path Std::string that contains path including filename of the file that should be created. + */ +void create_file_if_not_exist(std::string path) +{ + auto & v_cl = create_vcluster(); + if (v_cl.rank() == 0) + { + if ( ! check_if_file_exists(path)) + { + std::ofstream outfile (path); +// BOOST_LOG_TRIVIAL(info) << "Created file with name: " << path; + } + } +} + + +/**@brief Checks if a directory already exists. + * + * @param path Std::string with path of directory for which existence should be checked. + * @return True, if directory exists, false if not. + */ +bool check_if_directory_exists(std::string path) +{ + try + { + // Create a filesystem::path object from given path string + boost::filesystem::path pathObj(path); + if (boost::filesystem::exists(pathObj) && boost::filesystem::is_directory(pathObj)) return true; + } + catch (boost::filesystem::filesystem_error & e) + { + std::cerr << e.what() << std::endl; + } + return false; +} +/**@brief Creates a directory if not already existent. + * + * @param path Std::string that contains path including name of the folder that should be created. + */ +void create_directory_if_not_exist(std::string path) +{ + auto & v_cl = create_vcluster(); + if (v_cl.rank() == 0) + { + if ( ! check_if_directory_exists(path)) + { + boost::filesystem::create_directory(path); +// BOOST_LOG_TRIVIAL(info) << "Created directory with name: " << path; + } + else std::cout << "Folder for current settings ( '" << path << "' ) already exists. New files will be saved to this folder." << std::endl; +// BOOST_LOG_TRIVIAL(info) << "Folder for current settings ( '" << path << "' ) already exists. New files will be saved to this folder."; + } +} + + + + + +#endif //FILES_READ_AND_WRITE_PATHSANDFILES_HPP +