diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt deleted file mode 100644 index b14402393..000000000 --- a/tools/CMakeLists.txt +++ /dev/null @@ -1,136 +0,0 @@ -cmake_minimum_required (VERSION 2.8.12) - -# Setup cmake policies. -foreach(p - CMP0012 - CMP0013 - CMP0014 - CMP0022 # CMake 2.8.12 - CMP0025 # CMake 3.0 - CMP0053 # CMake 3.1 - CMP0054 # CMake 3.1 - CMP0074 # CMake 3.12 - CMP0075 # CMake 3.12 - CMP0083 # CMake 3.14 - CMP0093 # CMake 3.15 - ) - if(POLICY ${p}) - cmake_policy(SET ${p} NEW) - endif() -endforeach() - -project(PDC_VOL C) - -include_directories( - ${PDC_EXT_INCLUDE_DEPENDENCIES} -) - -find_package(PDC REQUIRED) -if(PDC_FOUND) - #message(STATUS "PDC include directory: ${PDC_INCLUDE_DIR}") - set(PDC_EXT_INCLUDE_DEPENDENCIES ${PDC_INCLUDE_DIR} - ${PDC_EXT_INCLUDE_DEPENDENCIES} - ) - set(PDC_EXT_LIB_DEPENDENCIES pdc ${PDC_EXT_LIB_DEPENDENCIES}) -endif() - -#HDF5 -option(USE_SYSTEM_HDF5 "Use system-installed HDF5." ON) - if(USE_SYSTEM_HDF5) - find_package(HDF5 NO_MODULE NAMES hdf5 COMPONENTS C shared) - if(HDF5_FOUND) - set(HDF5_C_SHARED_LIBRARY hdf5-shared) -# if(NOT TARGET ${HDF5_C_SHARED_LIBRARY}) -# message(FATAL_ERROR "Could not find hdf5 shared target, please make " -#"sure that HDF5 has ben compiled with shared libraries enabled.") -# endif() - set(PDC_EXT_INCLUDE_DEPENDENCIES - ${PDC_EXT_INCLUDE_DEPENDENCIES} - ${HDF5_INCLUDE_DIR} - ) - set(PDC_EXT_LIB_DEPENDENCIES - ${PDC_EXT_LIB_DEPENDENCIES} - ${HDF5_C_SHARED_LIBRARY} - ) - else() - # Allow for HDF5 autotools builds - find_package(HDF5 MODULE REQUIRED) - if(HDF5_FOUND) - set(PDC_EXT_INCLUDE_DEPENDENCIES - ${PDC_EXT_INCLUDE_DEPENDENCIES} - ${HDF5_INCLUDE_DIRS} - ) - set(PDC_EXT_LIB_DEPENDENCIES - ${PDC_EXT_LIB_DEPENDENCIES} - ${HDF5_LIBRARIES} - ) - else() - message(FATAL_ERROR "Could not find HDF5, please check HDF5_DIR.") - endif() - endif() -endif() - -option(USE_SYSTEM_OPENMP "Use system-installed OpenMP." ON) -if(USE_SYSTEM_OPENMP) - find_package(OpenMP REQUIRED) - if(OPENMP_FOUND) - add_definitions(-DENABLE_OPENMP=1) - set(ENABLE_OPENMP 1) - set(OPENMP_LIBRARIES "${OpenMP_C_LIBRARIES}") - else() - message(FATAL_ERROR "OpenMP not found") - endif() -endif() - - -add_definitions(-DENABLE_MPI=1) -add_library(cjson cjson/cJSON.c) - - -# set(PROGRAMS -# pdc_ls -# pdc_import -# pdc_export -# ) - -# foreach(program ${PROGRAMS}) -# add_executable(${program} ${program}.c) -# target_link_libraries(${program} ${PDC_EXT_LIB_DEPENDENCIES}) -# target_link_libraries(${program} pdc) -# target_link_libraries(${program} cjson) -# target_include_directories(${program} PUBLIC ${PDC_INCLUDE_DIR}) -# endforeach(program) - - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -fopenmp -DNDEBUG") - -# Find LibTIFF -option(USE_LIB_TIFF "Enable LibTiff." ON) -if(USE_LIB_TIFF) - find_package(TIFF REQUIRED) - if(TIFF_FOUND) - set(LLSM_LIB_SOURCE - llsm/parallelReadTiff.c - llsm/csvReader.c - llsm/pdc_list.c - ) - # Add the LibTIFF include directory to the include path - include_directories(${TIFF_INCLUDE_DIRS}) - add_library(llsm_tiff ${LLSM_LIB_SOURCE}) - target_compile_options(llsm_tiff PRIVATE ${OpenMP_C_FLAGS}) - target_link_libraries(llsm_tiff PUBLIC ${OpenMP_C_LIBRARIES}) - target_link_libraries(llsm_tiff PUBLIC ${TIFF_LIBRARIES}) - target_include_directories(llsm_tiff PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/llsm) - - - add_executable(llsm_importer llsm_importer.c) - target_link_libraries(llsm_importer ${PDC_EXT_LIB_DEPENDENCIES}) - target_link_libraries(llsm_importer pdc) - target_link_libraries(llsm_importer cjson) - target_link_libraries(llsm_importer ${TIFF_LIBRARIES}) - target_link_libraries(llsm_importer llsm_tiff) - target_include_directories(llsm_importer PUBLIC ${PDC_INCLUDE_DIR}) - else() - message(WARNING "LibTiff not found, ignore building the executables which requires LibTiff support.") - endif() -endif() \ No newline at end of file diff --git a/tools/LLSM_IMPORTER.md b/tools/LLSM_IMPORTER.md deleted file mode 100644 index 42ded7682..000000000 --- a/tools/LLSM_IMPORTER.md +++ /dev/null @@ -1,76 +0,0 @@ -# LLSM_Importer Tutorial - -This is a tutorial for you to run llsm_importer on Perlmutter supercomputer at NERSC. - -## Prerequisite - -Before building and installing LLSM_importer tool, you need to make sure you install PDC correctly. Check out the latest update on the `develop` branch of `PDC`. Please refer to [Proactive Data Containers (PDC) Installation Guide](../README.md) - -Once you finish all the steps in the installation guide above, you should have environment variable `$WORK_SPACE` defined. - -## Installation - -To build and install LLSM_importer, you need to download libtiff 4.4.0 first. - -```bash -cd $WORK_SPACE/source -wget https://download.osgeo.org/libtiff/tiff-4.4.0.tar.gz -tar zxvf tiff-4.4.0.tar.gz -cd tiff-4.4.0 -./configure --prefix=$WORK_SPACE/install/tiff-4.4.0 -make -j 32 install -``` - -Now you should have libtiff 4.4.0 installed and you need to include the path to the library to your environment variables: - -```bash -echo "export TIFF_DIR=$WORK_SPACE/install/tiff-4.4.0" -echo 'export LD_LIBRARY_PATH=$TIFF_DIR/lib:$LD_LIBRARY_PATH' -echo 'export PATH=$TIFF_DIR/include:$TIFF_DIR/lib:$PATH' - -echo "export TIFF_DIR=$WORK_SPACE/install/tiff-4.4.0" >> $WORK_SPACE/pdc_env.sh -echo 'export LD_LIBRARY_PATH=$TIFF_DIR/lib:$LD_LIBRARY_PATH' >> $WORK_SPACE/pdc_env.sh -echo 'export PATH=$TIFF_DIR/include:$TIFF_DIR/lib:$PATH' >> $WORK_SPACE/pdc_env.sh -``` - -Copy the 3 export commands on your screen and run them, and next time if you need to rebuild the llsm_importer program, you can run `$WORK_SPACE/pdc_env.sh` again in advance! - -Now, time to build llsm_importer program. - -```bash -mkdir -p $WORK_SPACE/source/pdc/tools/build -cd $WORK_SPACE/source/pdc/tools/build - -cmake ../ -DCMAKE_BUILD_TYPE=RelWithDebInfo -DPDC_DIR=$PDC_DIR -DUSE_LIB_TIFF=ON -DUSE_SYSTEM_HDF5=ON -DUSE_SYSTEM_OPENMP=ON -DCMAKE_INSTALL_PREFIX=$PDC_DIR/tools/ -DCMAKE_C_COMPILER=cc - -make -j 32 -``` - -After this, you should be able to see `llsm_importer` artifact under your `$WORK_SPACE/source/pdc/tools/build` directory. - -## Running LLSM_importer - -First, locate the llsm_importer script - -```bash -cd $WORK_SPACE/source/pdc/scripts/llsm_importer -``` - -Modify the template script `template.sh`. - -Change `EXECPATH` to where your `pdc_server.exe` is installed -Change `TOOLPATH` to where your `llsm_importer` artifact is. - -Change `LLSM_DATA_PATH` to where your sample dataset is. For exmaple, - -```bash -LLSM_DATA_PATH=/pscratch/sd/w/wzhang5/data/llsm/20220115_Korra_LLCPK_LFOV_0p1PSAmpKan/run1 -``` - -Note: you may download the sample dataset from the this [link](https://drive.google.com/file/d/19hH7v58iF_QBJ985ajwLD86MMseBH-YR/view?usp=sharing). It is provided with the courtesy of [Advanced BioImaging Center at UC Berkeley](https://mcb.berkeley.edu/faculty/cdb/upadhyayulas). - -Now, run `gen_script.sh` to generate scripts for different settings with various number of servers. - -After this, enter into any directory named with a number, and submit the job with `sbatch` command. - -Note: This program is still under development and changes will be made available from time to time. Please always use the develop branch for a stable version of this llsm_importer tool. \ No newline at end of file diff --git a/tools/llsm/csvReader.c b/tools/llsm/csvReader.c deleted file mode 100644 index c6623a287..000000000 --- a/tools/llsm/csvReader.c +++ /dev/null @@ -1,395 +0,0 @@ -#include "csvReader.h" - -char csv_delimiter = ','; -char csv_quote = '\"'; -char csv_escape = '\\'; -char csv_newline = '\n'; - -void -csv_set_delimiter(char delimiter) -{ - csv_delimiter = delimiter; -} - -void -csv_set_quote(char quote) -{ - csv_quote = quote; -} - -void -csv_set_escape(char escape) -{ - csv_escape = escape; -} - -void -csv_set_newline(char newline) -{ - csv_newline = newline; -} - -csv_header_t * -csv_parse_header(char *line, char *field_types) -{ - csv_header_t *first_header = NULL; - csv_header_t *last_header = NULL; - char * token = NULL; - char * saveptr = NULL; - int field_index = 0; - int in_quotes = 0; - int value_start = 0; - int i = 0; - - for (int i = 0; line[i] != csv_newline; ++i) { - if (line[i] == csv_quote) { - in_quotes = !in_quotes; - } - else if (!in_quotes && (line[i] == csv_delimiter || line[i + 1] == csv_newline)) { - // Allocate memory for the header struct - csv_header_t *header = (csv_header_t *)malloc(sizeof(csv_header_t)); - if (header == NULL) { - return NULL; - } - // Remove quotes and spaces from the field name - header->field_name = strndup(line + value_start, i - value_start + (line[i + 1] == csv_newline)); - - // Set the field index - header->field_index = field_index; - - // Set the field type - if (field_types != NULL) { - header->field_type = field_types[field_index]; - } - else { - header->field_type = 's'; - } - - // Set the next pointer to NULL - header->next = NULL; - - // Add the header to the linked list - if (first_header == NULL) { - first_header = header; - last_header = header; - } - else { - last_header->next = header; - last_header = header; - } - - value_start = i + 1; - field_index++; - } - } - - return first_header; -} - -csv_row_t * -csv_parse_row(char *line, csv_header_t *header) -{ - csv_cell_t * first_cell = NULL; - csv_cell_t * last_cell = NULL; - csv_header_t *current_header = header; - char * token = NULL; - char * saveptr = NULL; - int field_index = 0; - int in_quotes = 0; - int value_start = 0; - int i = 0; - - for (int i = 0; line[i] != csv_newline; ++i) { - if (line[i] == csv_quote) { - in_quotes = !in_quotes; - } - else if (!in_quotes && (line[i] == csv_delimiter || line[i + 1] == csv_newline)) { - // Allocate memory for the cell struct - csv_cell_t *cell = (csv_cell_t *)malloc(sizeof(csv_cell_t)); - if (cell == NULL) { - return NULL; - } - - // Set the field name - cell->header = current_header; - - // Set the field value - cell->field_value = strndup(line + value_start, i - value_start + (line[i + 1] == csv_newline)); - - // Set the next pointer to NULL - cell->next = NULL; - - // Add the cell to the linked list - if (first_cell == NULL) { - first_cell = cell; - last_cell = cell; - } - else { - last_cell->next = cell; - last_cell = cell; - } - - value_start = i + 1; - field_index++; - current_header = current_header->next; - } - } - csv_row_t *row = (csv_row_t *)malloc(sizeof(csv_row_t)); - row->first_cell = first_cell; - row->next = NULL; - return row; -} - -csv_cell_t * -csv_get_field_value_by_name(csv_row_t *row, csv_header_t *header, char *field_name) -{ - csv_cell_t *cell = row->first_cell; - while (cell != NULL) { - if (strcmp(cell->header->field_name, field_name) == 0) { - return cell; - } - cell = cell->next; - } - return NULL; -} - -csv_cell_t * -csv_get_field_value_by_index(csv_row_t *row, csv_header_t *header, int field_index) -{ - csv_cell_t *cell = row->first_cell; - while (cell != NULL) { - if (cell->header->field_index == field_index) { - return cell; - } - cell = cell->next; - } - return NULL; -} - -csv_table_t * -csv_parse_file(char *file_name, char *field_types) -{ - FILE *fp = fopen(file_name, "r"); - if (fp == NULL) { - return NULL; - } - - // Allocate memory for the table struct - csv_table_t *table = (csv_table_t *)malloc(sizeof(csv_table_t)); - if (table == NULL) { - return NULL; - } - - // Read the first line of the file - char * line = NULL; - size_t len = 0; - ssize_t read = getline(&line, &len, fp); - - // Parse the header - table->first_header = csv_parse_header(line, field_types); - - // Parse the rows - csv_row_t *first_row = NULL; - csv_row_t *last_row = NULL; - while ((read = getline(&line, &len, fp)) != -1) { - // Allocate memory for the row struct - csv_row_t *row = csv_parse_row(line, table->first_header); - if (row == NULL) { - return NULL; - } - - // Add the row to the linked list - if (first_row == NULL) { - first_row = row; - last_row = row; - } - else { - last_row->next = row; - last_row = row; - } - } - - table->first_row = first_row; - - return table; -} - -csv_table_t * -csv_parse_list(PDC_LIST *list, char *field_types) -{ - csv_table_t *table = (csv_table_t *)malloc(sizeof(csv_table_t)); - if (table == NULL) { - return NULL; - } - int num_file_read = 0; - csv_row_t *first_row = NULL; - csv_row_t *last_row = NULL; - - PDC_LIST_ITERATOR *iter = pdc_list_iterator_new(list); - while (pdc_list_iterator_has_next(iter)) { - char *line = (char *)pdc_list_iterator_next(iter); - if (num_file_read == 0) { - table->first_header = csv_parse_header(line, field_types); - } - else { - // Allocate memory for the row struct - csv_row_t *row = csv_parse_row(line, table->first_header); - if (row == NULL) { - return NULL; - } - - // Add the row to the linked list - if (first_row == NULL) { - first_row = row; - last_row = row; - } - else { - last_row->next = row; - last_row = row; - } - } - num_file_read++; - } - - table->first_row = first_row; - - return table; -} - -void -csv_free_header(csv_header_t *header) -{ - csv_header_t *current_header = header; - csv_header_t *next_header = NULL; - while (current_header != NULL) { - next_header = current_header->next; - free(current_header->field_name); - free(current_header); - current_header = next_header; - } -} - -void -csv_free_row(csv_row_t *row) -{ - csv_row_t *current_row = row; - csv_row_t *next_row = NULL; - while (current_row != NULL) { - next_row = current_row->next; - csv_free_cell(current_row->first_cell); - free(current_row); - current_row = next_row; - } -} - -void -csv_free_cell(csv_cell_t *cell) -{ - csv_cell_t *current_cell = cell; - csv_cell_t *next_cell = NULL; - while (current_cell != NULL) { - next_cell = current_cell->next; - free(current_cell->field_value); - free(current_cell); - current_cell = next_cell; - } -} - -void -csv_free_table(csv_table_t *table) -{ - csv_free_header(table->first_header); - csv_free_row(table->first_row); - free(table); -} - -void -csv_print_header(csv_header_t *header) -{ - csv_header_t *current_header = header; - while (current_header != NULL) { - printf("%s", current_header->field_name); - if (current_header->next != NULL) { - printf(", "); - } - current_header = current_header->next; - } - printf("\n"); -} - -void -csv_print_row(csv_row_t *row, int with_key) -{ - csv_cell_t *current_cell = row->first_cell; - while (current_cell != NULL) { - csv_print_cell(current_cell, with_key); - if (current_cell->next != NULL) { - printf(", "); - } - if (with_key) { - printf("\n"); - } - current_cell = current_cell->next; - } - printf("\n"); -} - -void -csv_print_cell(csv_cell_t *cell, int with_key) -{ - if (with_key) { - printf("%s: ", cell->header->field_name); - } - switch (cell->header->field_type) { - case 'i': - printf("%ld", strtol(cell->field_value, NULL, 10)); - break; - - case 'f': - printf("%f", strtod(cell->field_value, NULL)); - break; - - case 's': - printf("%s", cell->field_value); - break; - - default: - printf("%s", cell->field_value); - break; - } -} - -void -csv_print_table(csv_table_t *table) -{ - csv_print_header(table->first_header); - csv_row_t *current_row = table->first_row; - while (current_row != NULL) { - csv_print_row(current_row, 0); - current_row = current_row->next; - } -} - -int -csv_get_num_rows(csv_table_t *table) -{ - int num_rows = 0; - csv_row_t *current_row = table->first_row; - while (current_row != NULL) { - num_rows++; - current_row = current_row->next; - } - return num_rows; -} - -int -csv_get_num_fields(csv_table_t *table) -{ - int num_fields = 0; - csv_header_t *current_header = table->first_header; - while (current_header != NULL) { - num_fields++; - current_header = current_header->next; - } - return num_fields; -} \ No newline at end of file diff --git a/tools/llsm/csvReader.h b/tools/llsm/csvReader.h deleted file mode 100644 index d5aa87aaf..000000000 --- a/tools/llsm/csvReader.h +++ /dev/null @@ -1,190 +0,0 @@ -#ifndef CSVREADER_H -#define CSVREADER_H - -#include -#include -#include - -#include "pdc_list.h" - -typedef struct csv_header_t { - char * field_name; - int field_index; - char field_type; - struct csv_header_t *next; -} csv_header_t; - -typedef struct csv_cell_t { - char * field_value; - csv_header_t * header; - struct csv_cell_t *next; -} csv_cell_t; - -typedef struct csv_row_t { - csv_cell_t * first_cell; - struct csv_row_t *next; -} csv_row_t; - -typedef struct csv_table_t { - csv_header_t *first_header; - csv_row_t * first_row; -} csv_table_t; - -/** - * @brief This function sets the delimiter for the CSV file. The default is a comma. - * @param delimiter The delimiter to use. - */ -void csv_set_delimiter(char delimiter); - -/** - * @brief This function sets the quote character for the CSV file. The default is a double quote. - * @param quote The quote character to use. - */ -void csv_set_quote(char quote); - -/** - * @brief This function sets the escape character for the CSV file. The default is a backslash. - * @param escape The escape character to use. - */ -void csv_set_escape(char escape); - -/** - * @brief This function sets the newline character for the CSV file. The default is a newline. - * @param newline The newline character to use. - */ -void csv_set_newline(char newline); - -/** - * @brief This function parses a CSV header line and returns a linked list of csv_header_t structs. The header - * string may contain quotes and spaces - * @param line The CSV header line to parse. - * @param field_types A string of field types. The field types are 's' for string, 'i' for long integer, 'f' - * for float, and 'd' for double. If this is NULL, all fields are assumed to be strings. - * - * @return A pointer to the first csv_header_t struct in the linked list. - */ -csv_header_t *csv_parse_header(char *line, char *field_types); - -/** - * @brief This function parse a CSV row line and returns a linked list of csv_cell_t structs. The row string - * may contain quotes and spaces - * @param line The CSV row line to parse. - * @param header A pointer to the first csv_header_t struct in the linked list. - * - * @return A pointer to the csv_row_t struct. The value in the csv_cell should be - * free of quotes or spaces. - */ -csv_row_t *csv_parse_row(char *line, csv_header_t *header); - -/** - * @brief This function returns the string value of a field for a given row string. The row string may contain - * quotes and spaces - * @param row The CSV row to look for. - * @param header A pointer to the first csv_header_t struct in the linked list. - * @param field_name The name of the field to get the value for. - * - * @return A pointer to the csv_cell struct of the field. The value in the csv_cell should be free of quotes - * or spaces. - */ -csv_cell_t *csv_get_field_value_by_name(csv_row_t *row, csv_header_t *header, char *field_name); - -/** - * @brief This function returns the string value of a field for a given row string. The row string may contain - * quotes and spaces - * @param row The CSV row to look for. - * @param header A pointer to the first csv_header_t struct in the linked list. - * @param field_index The index of the field to get the value for. - * - * @return A pointer to the csv_cell struct of the field. The value in the csv_cell should be free of quotes - * or spaces. - */ -csv_cell_t *csv_get_field_value_by_index(csv_row_t *row, csv_header_t *header, int field_index); - -/** - * @brief This function parses a CSV file and returns a csv_table_t struct. - * @param file_name The name of the CSV file to parse. - * @param field_types A string of field types. The field types are 's' for string, 'i' for long integer, 'f' - * for float, and 'd' for double. If this is NULL, all fields are assumed to be strings. - * - * @return A pointer to the csv_table_t struct. - */ -csv_table_t *csv_parse_file(char *file_name, char *field_types); - -/** - * @brief This function parses a PDC_LIST of strings as a CSV file and returns a csv_table_t struct. - * @param list A PDC_LIST of strings to parse. - * @param field_types A string of field types. The field types are 's' for string, 'i' for long integer, 'f' - * for float, and 'd' for double. If this is NULL, all fields are assumed to be strings. - * - * @return A pointer to the csv_table_t struct. - */ -csv_table_t *csv_parse_list(PDC_LIST *list, char *field_types); - -/** - * @brief This function frees the memory allocated for a csv_table_t struct. - * @param table A pointer to the csv_table_t struct to free. - */ -void csv_free_table(csv_table_t *table); - -/** - * @brief This function frees the memory allocated for a csv_header_t struct. - * @param header A pointer to the csv_header_t struct to free. - */ -void csv_free_header(csv_header_t *header); - -/** - * @brief This function frees the memory allocated for a csv_row_t struct. - * @param row A pointer to the csv_row_t struct to free. - */ -void csv_free_row(csv_row_t *row); - -/** - * @brief This function frees the memory allocated for a csv_cell_t struct. - * @param cell A pointer to the csv_cell_t struct to free. - */ -void csv_free_cell(csv_cell_t *cell); - -/** - * @brief This function prints the contents of a csv_table_t struct. - * @param table A pointer to the csv_table_t struct to print. - */ -void csv_print_table(csv_table_t *table); - -/** - * @brief This function prints the contents of a csv_header_t struct. - * @param header A pointer to the csv_header_t struct to print. - */ -void csv_print_header(csv_header_t *header); - -/** - * @brief This function prints the contents of a csv_row_t struct. - * @param row A pointer to the csv_row_t struct to print. - * @param with_key A flag to indicate whether to print the key or not. - */ - -void csv_print_row(csv_row_t *row, int with_key); - -/** - * @brief This function prints the contents of a csv_cell_t struct. - * @param cell A pointer to the csv_cell_t struct to print. - * @param with_key A flag to indicate whether to print the key or not. - */ -void csv_print_cell(csv_cell_t *cell, int with_key); - -/** - * @brief This function returns the number of rows in a csv_table_t struct. - * @param table A pointer to the csv_table_t struct. - * - * @return The number of rows in the table. - */ -int csv_get_num_rows(csv_table_t *table); - -/** - * @brief This function returns the number of fields in a csv_table_t struct. - * @param table A pointer to the csv_table_t struct. - * - * @return The number of fields in the table. - */ -int csv_get_num_fields(csv_table_t *table); - -#endif // CSVREADER_H \ No newline at end of file diff --git a/tools/llsm/parallelReadTiff.c b/tools/llsm/parallelReadTiff.c deleted file mode 100644 index cc4026ac9..000000000 --- a/tools/llsm/parallelReadTiff.c +++ /dev/null @@ -1,818 +0,0 @@ -#include "parallelReadTiff.h" -#include "tiffio.h" - -#define ENABLE_OPENMP - -#ifdef ENABLE_OPENMP -#include "omp.h" -#endif - -#define CREATE_ARRAY(result_var, type, ndim, dim) \ - do { \ - size_t i = 0, dim_prod = 1; \ - for (i = 0; i < (ndim); i++) { \ - dim_prod *= (dim)[i]; \ - } \ - result_var = (void *)malloc(dim_prod * sizeof(type)); \ - } while (0) - -void -DummyHandler(const char *module, const char *fmt, va_list ap) -{ - // ignore errors and warnings -} - -// Backup method in case there are errors reading strips -void -readTiffParallelBak(uint64_t x, uint64_t y, uint64_t z, const char *fileName, void *tiff, uint64_t bits, - uint64_t startSlice, uint8_t flipXY) -{ - int32_t numWorkers = omp_get_max_threads(); - int32_t batchSize = (z - 1) / numWorkers + 1; - uint64_t bytes = bits / 8; - - printf("numWorkers %d\n", numWorkers); - - int32_t w; -#ifdef ENABLE_OPENMP -#pragma omp parallel for -#endif - for (w = 0; w < numWorkers; w++) { - - TIFF *tif = TIFFOpen(fileName, "r"); - if (!tif) - printf("tiff:threadError | Thread %d: File \"%s\" cannot be opened\n", w, fileName); - - void *buffer = malloc(x * bytes); - for (int64_t dir = startSlice + (w * batchSize); dir < startSlice + ((w + 1) * batchSize); dir++) { - if (dir >= z + startSlice) - break; - - int counter = 0; - while (!TIFFSetDirectory(tif, (uint64_t)dir) && counter < 3) { - printf("Thread %d: File \"%s\" Directory \"%d\" failed to open. Try %d\n", w, fileName, dir, - counter + 1); - counter++; - } - - for (int64_t i = 0; i < y; i++) { - TIFFReadScanline(tif, buffer, i, 0); - if (!flipXY) { - memcpy(tiff + ((i * x) * bytes), buffer, x * bytes); - continue; - } - // loading the data into a buffer - switch (bits) { - case 8: - // Map Values to flip x and y for MATLAB - for (int64_t j = 0; j < x; j++) { - ((uint8_t *)tiff)[((j * y) + i) + ((dir - startSlice) * (x * y))] = - ((uint8_t *)buffer)[j]; - } - break; - case 16: - // Map Values to flip x and y for MATLAB - for (int64_t j = 0; j < x; j++) { - ((uint16_t *)tiff)[((j * y) + i) + ((dir - startSlice) * (x * y))] = - ((uint16_t *)buffer)[j]; - } - break; - case 32: - // Map Values to flip x and y for MATLAB - for (int64_t j = 0; j < x; j++) { - ((float *)tiff)[((j * y) + i) + ((dir - startSlice) * (x * y))] = - ((float *)buffer)[j]; - } - break; - case 64: - // Map Values to flip x and y for MATLAB - for (int64_t j = 0; j < x; j++) { - ((double *)tiff)[((j * y) + i) + ((dir - startSlice) * (x * y))] = - ((double *)buffer)[j]; - } - break; - } - } - } - free(buffer); - TIFFClose(tif); - } -} - -void -readTiffParallel(uint64_t x, uint64_t y, uint64_t z, const char *fileName, void *tiff, uint64_t bits, - uint64_t startSlice, uint64_t stripSize, uint8_t flipXY) -{ - int32_t numWorkers = omp_get_max_threads(); - int32_t batchSize = (z - 1) / numWorkers + 1; - uint64_t bytes = bits / 8; - - printf("numWorkers %d\n", numWorkers); - - uint16_t compressed = 1; - TIFF * tif = TIFFOpen(fileName, "r"); - TIFFGetField(tif, TIFFTAG_COMPRESSION, &compressed); - - int32_t w; - uint8_t errBak = 0; - uint8_t err = 0; - char errString[10000]; - if (compressed > 1 || z < 32768) { - TIFFClose(tif); -#ifdef ENABLE_OPENMP -#pragma omp parallel for -#endif - for (w = 0; w < numWorkers; w++) { - - uint8_t outCounter = 0; - TIFF * tif = TIFFOpen(fileName, "r"); - while (!tif) { - tif = TIFFOpen(fileName, "r"); - if (outCounter == 3) { -#ifdef ENABLE_OPENMP -#pragma omp critical -#endif - { - err = 1; - sprintf(errString, "Thread %d: File \"%s\" cannot be opened\n", w, fileName); - } - continue; - } - outCounter++; - } - - void *buffer = malloc(x * stripSize * bytes); - for (int64_t dir = startSlice + (w * batchSize); dir < startSlice + ((w + 1) * batchSize); - dir++) { - if (dir >= z + startSlice || err) - break; - - uint8_t counter = 0; - while (!TIFFSetDirectory(tif, (uint64_t)dir) && counter < 3) { - counter++; - if (counter == 3) { -#ifdef ENABLE_OPENMP -#pragma omp critical -#endif - { - err = 1; - sprintf(errString, "Thread %d: File \"%s\" cannot be opened\n", w, fileName); - } - } - } - if (err) - break; - for (int64_t i = 0; i * stripSize < y; i++) { - - // loading the data into a buffer - int64_t cBytes = TIFFReadEncodedStrip(tif, i, buffer, stripSize * x * bytes); - if (cBytes < 0) { -#ifdef ENABLE_OPENMP -#pragma omp critical -#endif - { - errBak = 1; - err = 1; - sprintf(errString, "Thread %d: Strip %ld cannot be read\n", w, i); - } - break; - } - if (!flipXY) { - memcpy(tiff + ((i * stripSize * x) * bytes), buffer, cBytes); - continue; - } - switch (bits) { - case 8: - // Map Values to flip x and y for MATLAB - for (int64_t k = 0; k < stripSize; k++) { - if ((k + (i * stripSize)) >= y) - break; - for (int64_t j = 0; j < x; j++) { - ((uint8_t *)tiff)[((j * y) + (k + (i * stripSize))) + - ((dir - startSlice) * (x * y))] = - ((uint8_t *)buffer)[j + (k * x)]; - } - } - break; - case 16: - // Map Values to flip x and y for MATLAB - for (int64_t k = 0; k < stripSize; k++) { - if ((k + (i * stripSize)) >= y) - break; - for (int64_t j = 0; j < x; j++) { - ((uint16_t *)tiff)[((j * y) + (k + (i * stripSize))) + - ((dir - startSlice) * (x * y))] = - ((uint16_t *)buffer)[j + (k * x)]; - } - } - break; - case 32: - // Map Values to flip x and y for MATLAB - for (int64_t k = 0; k < stripSize; k++) { - if ((k + (i * stripSize)) >= y) - break; - for (int64_t j = 0; j < x; j++) { - ((float *)tiff)[((j * y) + (k + (i * stripSize))) + - ((dir - startSlice) * (x * y))] = - ((float *)buffer)[j + (k * x)]; - } - } - break; - case 64: - // Map Values to flip x and y for MATLAB - for (int64_t k = 0; k < stripSize; k++) { - if ((k + (i * stripSize)) >= y) - break; - for (int64_t j = 0; j < x; j++) { - ((double *)tiff)[((j * y) + (k + (i * stripSize))) + - ((dir - startSlice) * (x * y))] = - ((double *)buffer)[j + (k * x)]; - } - } - break; - } - } - } - free(buffer); - TIFFClose(tif); - } - } - else { - uint64_t stripsPerDir = (uint64_t)ceil((double)y / (double)stripSize); -#ifdef _WIN32 - int fd = open(fileName, O_RDONLY | O_BINARY); -#else - int fd = open(fileName, O_RDONLY); -#endif - if (fd == -1) - printf("disk:threadError | File \"%s\" cannot be opened from Disk\n", fileName); - - if (!tif) - printf("tiff:threadError | File \"%s\" cannot be opened\n", fileName); - uint64_t offset = 0; - uint64_t *offsets = NULL; - TIFFGetField(tif, TIFFTAG_STRIPOFFSETS, &offsets); - uint64_t *byteCounts = NULL; - TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &byteCounts); - if (!offsets || !byteCounts) - printf("tiff:threadError | Could not get offsets or byte counts from the tiff file\n"); - offset = offsets[0]; - uint64_t fOffset = offsets[stripsPerDir - 1] + byteCounts[stripsPerDir - 1]; - uint64_t zSize = fOffset - offset; - TIFFSetDirectory(tif, 1); - TIFFGetField(tif, TIFFTAG_STRIPOFFSETS, &offsets); - uint64_t gap = offsets[0] - fOffset; - - lseek(fd, offset, SEEK_SET); - - TIFFClose(tif); - uint64_t curr = 0; - uint64_t bytesRead = 0; - // TESTING - // Not sure if we will need to read in chunks like for ImageJ - for (uint64_t i = 0; i < z; i++) { - bytesRead = read(fd, tiff + curr, zSize); - curr += bytesRead; - lseek(fd, gap, SEEK_CUR); - } - close(fd); - uint64_t size = x * y * z * (bits / 8); - void * tiffC = malloc(size); - memcpy(tiffC, tiff, size); -#ifdef ENABLE_OPENMP -#pragma omp parallel for -#endif - for (uint64_t k = 0; k < z; k++) { - for (uint64_t j = 0; j < x; j++) { - for (uint64_t i = 0; i < y; i++) { - switch (bits) { - case 8: - ((uint8_t *)tiff)[i + (j * y) + (k * x * y)] = - ((uint8_t *)tiffC)[j + (i * x) + (k * x * y)]; - break; - case 16: - ((uint16_t *)tiff)[i + (j * y) + (k * x * y)] = - ((uint16_t *)tiffC)[j + (i * x) + (k * x * y)]; - break; - case 32: - ((float *)tiff)[i + (j * y) + (k * x * y)] = - ((float *)tiffC)[j + (i * x) + (k * x * y)]; - break; - case 64: - ((double *)tiff)[i + (j * y) + (k * x * y)] = - ((double *)tiffC)[j + (i * x) + (k * x * y)]; - break; - } - } - } - } - free(tiffC); - } - if (err) { - if (errBak) - readTiffParallelBak(x, y, z, fileName, tiff, bits, startSlice, flipXY); - else - printf("tiff:threadError %s\n", errString); - } -} - -// Backup method in case there are errors reading strips -void -readTiffParallel2DBak(uint64_t x, uint64_t y, uint64_t z, const char *fileName, void *tiff, uint64_t bits, - uint64_t startSlice, uint8_t flipXY) -{ - int32_t numWorkers = omp_get_max_threads(); - int32_t batchSize = (y - 1) / numWorkers + 1; - uint64_t bytes = bits / 8; - - printf("numWorkers %d\n", numWorkers); - - int32_t w; -#ifdef ENABLE_OPENMP -#pragma omp parallel for -#endif - for (w = 0; w < numWorkers; w++) { - - TIFF *tif = TIFFOpen(fileName, "r"); - if (!tif) - printf("tiff:threadError | Thread %d: File \"%s\" cannot be opened\n", w, fileName); - - void *buffer = malloc(x * bytes); - for (int64_t dir = startSlice + (w * batchSize); dir < startSlice + ((w + 1) * batchSize); dir++) { - if (dir >= z + startSlice) - break; - - int counter = 0; - while (!TIFFSetDirectory(tif, (uint64_t)0) && counter < 3) { - printf("Thread %d: File \"%s\" Directory \"%d\" failed to open. Try %d\n", w, fileName, dir, - counter + 1); - counter++; - } - - for (int64_t i = (w * batchSize); i < ((w + 1) * batchSize); i++) { - if (i >= y) - break; - TIFFReadScanline(tif, buffer, i, 0); - if (!flipXY) { - memcpy(tiff + ((i * x) * bytes), buffer, x * bytes); - continue; - } - // loading the data into a buffer - switch (bits) { - case 8: - // Map Values to flip x and y for MATLAB - for (int64_t j = 0; j < x; j++) { - ((uint8_t *)tiff)[((j * y) + i) + ((dir - startSlice) * (x * y))] = - ((uint8_t *)buffer)[j]; - } - break; - case 16: - // Map Values to flip x and y for MATLAB - for (int64_t j = 0; j < x; j++) { - ((uint16_t *)tiff)[((j * y) + i) + ((dir - startSlice) * (x * y))] = - ((uint16_t *)buffer)[j]; - } - break; - case 32: - // Map Values to flip x and y for MATLAB - for (int64_t j = 0; j < x; j++) { - ((float *)tiff)[((j * y) + i) + ((dir - startSlice) * (x * y))] = - ((float *)buffer)[j]; - } - break; - case 64: - // Map Values to flip x and y for MATLAB - for (int64_t j = 0; j < x; j++) { - ((double *)tiff)[((j * y) + i) + ((dir - startSlice) * (x * y))] = - ((double *)buffer)[j]; - } - break; - } - } - } - free(buffer); - TIFFClose(tif); - } -} - -void -readTiffParallel2D(uint64_t x, uint64_t y, uint64_t z, const char *fileName, void *tiff, uint64_t bits, - uint64_t startSlice, uint64_t stripSize, uint8_t flipXY) -{ - int32_t numWorkers = omp_get_max_threads(); - uint64_t stripsPerDir = (uint64_t)ceil((double)y / (double)stripSize); - int32_t batchSize = (stripsPerDir - 1) / numWorkers + 1; - uint64_t bytes = bits / 8; - - int32_t w; - uint8_t err = 0; - uint8_t errBak = 0; - char errString[10000]; - - printf("numWorkers %d\n", numWorkers); - -#ifdef ENABLE_OPENMP -#pragma omp parallel for -#endif - for (w = 0; w < numWorkers; w++) { - - uint8_t outCounter = 0; - TIFF * tif = TIFFOpen(fileName, "r"); - while (!tif) { - tif = TIFFOpen(fileName, "r"); - if (outCounter == 3) { -#ifdef ENABLE_OPENMP -#pragma omp critical -#endif - { - err = 1; - sprintf(errString, "Thread %d: File \"%s\" cannot be opened\n", w, fileName); - } - continue; - } - outCounter++; - } - - void *buffer = malloc(x * stripSize * bytes); - - uint8_t counter = 0; - while (!TIFFSetDirectory(tif, 0) && counter < 3) { - printf("Thread %d: File \"%s\" Directory \"%d\" failed to open. Try %d\n", w, fileName, 0, - counter + 1); - counter++; - if (counter == 3) { -#ifdef ENABLE_OPENMP -#pragma omp critical -#endif - { - err = 1; - sprintf(errString, "Thread %d: File \"%s\" cannot be opened\n", w, fileName); - } - } - } - for (int64_t i = (w * batchSize); i < (w + 1) * batchSize; i++) { - if (i * stripSize >= y || err) - break; - // loading the data into a buffer - int64_t cBytes = TIFFReadEncodedStrip(tif, i, buffer, stripSize * x * bytes); - if (cBytes < 0) { -#ifdef ENABLE_OPENMP -#pragma omp critical -#endif - { - errBak = 1; - err = 1; - sprintf(errString, "Thread %d: Strip %ld cannot be read\n", w, i); - } - break; - } - if (!flipXY) { - memcpy(tiff + ((i * stripSize * x) * bytes), buffer, cBytes); - continue; - } - switch (bits) { - case 8: - // Map Values to flip x and y for MATLAB - for (int64_t k = 0; k < stripSize; k++) { - if ((k + (i * stripSize)) >= y) - break; - for (int64_t j = 0; j < x; j++) { - ((uint8_t *)tiff)[((j * y) + (k + (i * stripSize)))] = - ((uint8_t *)buffer)[j + (k * x)]; - } - } - break; - case 16: - // Map Values to flip x and y for MATLAB - for (int64_t k = 0; k < stripSize; k++) { - if ((k + (i * stripSize)) >= y) - break; - for (int64_t j = 0; j < x; j++) { - ((uint16_t *)tiff)[((j * y) + (k + (i * stripSize)))] = - ((uint16_t *)buffer)[j + (k * x)]; - } - } - break; - case 32: - // Map Values to flip x and y for MATLAB - for (int64_t k = 0; k < stripSize; k++) { - if ((k + (i * stripSize)) >= y) - break; - for (int64_t j = 0; j < x; j++) { - ((float *)tiff)[((j * y) + (k + (i * stripSize)))] = - ((float *)buffer)[j + (k * x)]; - } - } - break; - case 64: - // Map Values to flip x and y for MATLAB - for (int64_t k = 0; k < stripSize; k++) { - if ((k + (i * stripSize)) >= y) - break; - for (int64_t j = 0; j < x; j++) { - ((double *)tiff)[((j * y) + (k + (i * stripSize)))] = - ((double *)buffer)[j + (k * x)]; - } - } - break; - } - } - free(buffer); - TIFFClose(tif); - } - - if (err) { - if (errBak) - readTiffParallel2DBak(x, y, z, fileName, tiff, bits, startSlice, flipXY); - else - printf("tiff:threadError %s\n", errString); - } -} - -// Reading images saved by ImageJ -void -readTiffParallelImageJ(uint64_t x, uint64_t y, uint64_t z, const char *fileName, void *tiff, uint64_t bits, - uint64_t startSlice, uint64_t stripSize, uint8_t flipXY) -{ -#ifdef _WIN32 - int fd = open(fileName, O_RDONLY | O_BINARY); -#else - int fd = open(fileName, O_RDONLY); -#endif - TIFF *tif = TIFFOpen(fileName, "r"); - if (!tif) - printf("tiff:threadError | File \"%s\" cannot be opened\n", fileName); - uint64_t offset = 0; - uint64_t *offsets = NULL; - TIFFGetField(tif, TIFFTAG_STRIPOFFSETS, &offsets); - if (offsets) - offset = offsets[0]; - - TIFFClose(tif); - lseek(fd, offset, SEEK_SET); - uint64_t bytes = bits / 8; - // #pragma omp parallel for - /* - for(uint64_t i = 0; i < z; i++){ - uint64_t cOffset = x*y*bytes*i; - //pread(fd,tiff+cOffset,x*y*bytes,offset+cOffset); - read(fd,tiff+cOffset,x*y*bytes); - }*/ - uint64_t chunk = 0; - uint64_t tBytes = x * y * z * bytes; - uint64_t bytesRead; - uint64_t rBytes = tBytes; - if (tBytes < INT_MAX) - bytesRead = read(fd, tiff, tBytes); - else { - while (chunk < tBytes) { - rBytes = tBytes - chunk; - if (rBytes > INT_MAX) - bytesRead = read(fd, tiff + chunk, INT_MAX); - else - bytesRead = read(fd, tiff + chunk, rBytes); - chunk += bytesRead; - } - } - close(fd); - // Swap endianess for types greater than 8 bits - // TODO: May need to change later because we may not always need to swap - if (bits > 8) { -#ifdef ENABLE_OPENMP -#pragma omp parallel for -#endif - for (uint64_t i = 0; i < x * y * z; i++) { - switch (bits) { - case 16: - //((uint16_t*)tiff)[i] = ((((uint16_t*)tiff)[i] & 0xff) >> 8) | (((uint16_t*)tiff)[i] << - // 8); - //((uint16_t*)tiff)[i] = bswap_16(((uint16_t*)tiff)[i]); - ((uint16_t *)tiff)[i] = - ((((uint16_t *)tiff)[i] << 8) & 0xff00) | ((((uint16_t *)tiff)[i] >> 8) & 0x00ff); - break; - case 32: - //((num & 0xff000000) >> 24) | ((num & 0x00ff0000) >> 8) | ((num & 0x0000ff00) << 8) | - //(num << 24) - //((float*)tiff)[i] = bswap_32(((float*)tiff)[i]); - ((uint32_t *)tiff)[i] = ((((uint32_t *)tiff)[i] << 24) & 0xff000000) | - ((((uint32_t *)tiff)[i] << 8) & 0x00ff0000) | - ((((uint32_t *)tiff)[i] >> 8) & 0x0000ff00) | - ((((uint32_t *)tiff)[i] >> 24) & 0x000000ff); - break; - case 64: - //((double*)tiff)[i] = bswap_64(((double*)tiff)[i]); - ((uint64_t *)tiff)[i] = ((((uint64_t *)tiff)[i] << 56) & 0xff00000000000000UL) | - ((((uint64_t *)tiff)[i] << 40) & 0x00ff000000000000UL) | - ((((uint64_t *)tiff)[i] << 24) & 0x0000ff0000000000UL) | - ((((uint64_t *)tiff)[i] << 8) & 0x000000ff00000000UL) | - ((((uint64_t *)tiff)[i] >> 8) & 0x00000000ff000000UL) | - ((((uint64_t *)tiff)[i] >> 24) & 0x0000000000ff0000UL) | - ((((uint64_t *)tiff)[i] >> 40) & 0x000000000000ff00UL) | - ((((uint64_t *)tiff)[i] >> 56) & 0x00000000000000ffUL); - break; - } - } - } - // Find a way to do this in-place without making a copy - if (flipXY) { - uint64_t size = x * y * z * (bits / 8); - void * tiffC = malloc(size); - memcpy(tiffC, tiff, size); -#ifdef ENABLE_OPENMP -#pragma omp parallel for -#endif - for (uint64_t k = 0; k < z; k++) { - for (uint64_t j = 0; j < x; j++) { - for (uint64_t i = 0; i < y; i++) { - switch (bits) { - case 8: - ((uint8_t *)tiff)[i + (j * y) + (k * x * y)] = - ((uint8_t *)tiffC)[j + (i * x) + (k * x * y)]; - break; - case 16: - ((uint16_t *)tiff)[i + (j * y) + (k * x * y)] = - ((uint16_t *)tiffC)[j + (i * x) + (k * x * y)]; - break; - case 32: - ((float *)tiff)[i + (j * y) + (k * x * y)] = - ((float *)tiffC)[j + (i * x) + (k * x * y)]; - break; - case 64: - ((double *)tiff)[i + (j * y) + (k * x * y)] = - ((double *)tiffC)[j + (i * x) + (k * x * y)]; - break; - } - } - } - } - free(tiffC); - } -} - -uint8_t -isImageJIm(TIFF *tif) -{ - if (!tif) - return 0; - char *tiffDesc = NULL; - if (TIFFGetField(tif, TIFFTAG_IMAGEDESCRIPTION, &tiffDesc)) { - if (strstr(tiffDesc, "ImageJ")) { - return 1; - } - } - return 0; -} - -uint64_t -imageJImGetZ(TIFF *tif) -{ - if (!tif) - return 0; - char *tiffDesc = NULL; - if (TIFFGetField(tif, TIFFTAG_IMAGEDESCRIPTION, &tiffDesc)) { - if (strstr(tiffDesc, "ImageJ")) { - char *nZ = strstr(tiffDesc, "images="); - if (nZ) { - nZ += 7; - char *temp; - return strtol(nZ, &temp, 10); - } - } - } - return 0; -} - -void -get_tiff_info(char *fileName, parallel_tiff_range_t *strip_range, uint64_t *x, uint64_t *y, uint64_t *z, - uint64_t *bits, uint64_t *startSlice, uint64_t *stripSize, uint64_t *is_imageJ, - uint64_t *imageJ_Z) -{ - TIFFSetWarningHandler(DummyHandler); - TIFF *tif = TIFFOpen(fileName, "r"); - if (!tif) - printf("tiff:inputError | File \"%s\" cannot be opened", fileName); - - TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, x); - TIFFGetField(tif, TIFFTAG_IMAGELENGTH, y); - - if (strip_range == NULL) { - uint16_t s = 0, m = 0, t = 1; - while (TIFFSetDirectory(tif, t)) { - s = t; - t *= 8; - if (s > t) { - t = 65535; - printf("Number of slices > 32768\n"); - break; - } - } - while (s != t) { - m = (s + t + 1) / 2; - if (TIFFSetDirectory(tif, m)) { - s = m; - } - else { - if (m > 0) - t = m - 1; - else - t = m; - } - } - *z = s + 1; - } - else { - if (strip_range->length != 2) { - printf("tiff:inputError | Input range is not 2"); - } - else { - *startSlice = (uint64_t)(*(strip_range->range)) - 1; - *z = (uint64_t)(*(strip_range->range + 1)) - startSlice[0]; - if (!TIFFSetDirectory(tif, startSlice[0] + z[0] - 1) || !TIFFSetDirectory(tif, startSlice[0])) { - printf("tiff:rangeOutOfBound | Range is out of bounds"); - } - } - } - - *is_imageJ = isImageJIm(tif); - *imageJ_Z = imageJImGetZ(tif); - if (*is_imageJ) { - *is_imageJ = 1; - *imageJ_Z = imageJImGetZ(tif); - if (*imageJ_Z) - *z = *imageJ_Z; - } - - TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, bits); - TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, stripSize); - TIFFClose(tif); -} - -void * -_get_tiff_array(int bits, int ndim, size_t *dims) -{ - void *tiff = NULL; - if (bits == 8) { - CREATE_ARRAY(tiff, uint8_t, ndim, dims); - } - else if (bits == 16) { - CREATE_ARRAY(tiff, uint16_t, ndim, dims); - } - else if (bits == 32) { - CREATE_ARRAY(tiff, float, ndim, dims); - } - else if (bits == 64) { - CREATE_ARRAY(tiff, double, ndim, dims); - } - return tiff; -} - -void -_TIFF_load(char *fileName, uint8_t isImageJIm, uint64_t x, uint64_t y, uint64_t z, uint64_t bits, - uint64_t startSlice, uint64_t stripSize, uint8_t flipXY, int ndim, size_t *dims, void **tiff_ptr) -{ - if (tiff_ptr == NULL) { - printf("tiff:dataTypeError, Data type not suppported\n"); - } - *tiff_ptr = _get_tiff_array(bits, ndim, dims); - // Case for ImageJ - if (isImageJIm) { - readTiffParallelImageJ(x, y, z, fileName, *tiff_ptr, bits, startSlice, stripSize, flipXY); - } - // Case for 2D - else if (z <= 1) { - readTiffParallel2D(x, y, z, fileName, *tiff_ptr, bits, startSlice, stripSize, flipXY); - } - // Case for 3D - else { - readTiffParallel(x, y, z, fileName, *tiff_ptr, bits, startSlice, stripSize, flipXY); - } -} - -void -parallel_TIFF_load(char *fileName, uint8_t flipXY, parallel_tiff_range_t *strip_range, - image_info_t **image_info) -{ - uint64_t x = 1, y = 1, z = 1, bits = 1, startSlice = 0, stripeSize = 1, is_imageJ = 0, imageJ_Z = 0; - - get_tiff_info(fileName, strip_range, &x, &y, &z, &bits, &startSlice, &stripeSize, &is_imageJ, &imageJ_Z); - - int ndim = 3; - uint64_t dims[ndim]; - dims[0] = flipXY ? y : x; - dims[1] = flipXY ? x : y; - dims[2] = z; - - *image_info = (image_info_t *)malloc(sizeof(image_info_t)); - (*image_info)->x = dims[0]; - (*image_info)->y = dims[1]; - (*image_info)->z = dims[2]; - (*image_info)->bits = bits; - (*image_info)->startSlice = startSlice; - (*image_info)->stripeSize = stripeSize; - (*image_info)->is_imageJ = is_imageJ; - (*image_info)->imageJ_Z = imageJ_Z; - (*image_info)->tiff_size = dims[0] * dims[1] * dims[2] * (bits / 8); - - _TIFF_load(fileName, is_imageJ, x, y, z, bits, startSlice, stripeSize, flipXY, ndim, dims, - (void **)&((*image_info)->tiff_ptr)); -} \ No newline at end of file diff --git a/tools/llsm/parallelReadTiff.h b/tools/llsm/parallelReadTiff.h deleted file mode 100644 index 081640110..000000000 --- a/tools/llsm/parallelReadTiff.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef PARALLELREADTIFF_H -#define PARALLELREADTIFF_H - -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct { - uint64_t *range; - size_t length; -} parallel_tiff_range_t; - -typedef struct { - uint64_t x; - uint64_t y; - uint64_t z; - uint64_t bits; - uint64_t startSlice; - uint64_t stripeSize; - uint64_t is_imageJ; - uint64_t imageJ_Z; - void * tiff_ptr; - size_t tiff_size; -} image_info_t; - -void parallel_TIFF_load(char *fileName, uint8_t flipXY, parallel_tiff_range_t *strip_range, - image_info_t **image_info_t); - -#endif // PARALLELREADTIFF_H \ No newline at end of file diff --git a/tools/llsm/pdc_list.c b/tools/llsm/pdc_list.c deleted file mode 100644 index 95c6e59e7..000000000 --- a/tools/llsm/pdc_list.c +++ /dev/null @@ -1,165 +0,0 @@ -#include "pdc_list.h" - -PDC_LIST * -pdc_list_new() -{ - return pdc_list_create(100, 2.0); -} - -PDC_LIST * -pdc_list_create(size_t initial_capacity, double expansion_factor) -{ - // Allocate memory for the list struct. - PDC_LIST *list = (PDC_LIST *)malloc(sizeof(PDC_LIST)); - if (list == NULL) { - return NULL; - } - - // Allocate memory for the array of items. - list->items = (void **)malloc(initial_capacity * sizeof(void *)); - if (list->items == NULL) { - free(list); - return NULL; - } - - // Initialize the list fields. - list->item_count = 0; - list->capacity = initial_capacity; - list->expansion_factor = expansion_factor; - - return list; -} - -void -pdc_list_destroy(PDC_LIST *list) -{ - if (list == NULL) { - return; - } - - // Free all allocated memory for each item. - for (size_t i = 0; i < list->item_count; i++) { - free(list->items[i]); - } - - // Free the array of items and the list struct. - free(list->items); - free(list); -} - -void -pdc_list_add(PDC_LIST *list, void *item) -{ - if (list == NULL || item == NULL) { - return; - } - - // Expand the array of items if necessary. - if (list->item_count >= list->capacity) { - list->capacity *= list->expansion_factor; - list->items = (void **)realloc(list->items, list->capacity * sizeof(void *)); - if (list->items == NULL) { - return; - } - } - - // Add the new item to the end of the array. - list->items[list->item_count++] = item; -} - -void * -pdc_list_get(PDC_LIST *list, size_t index) -{ - if (list == NULL || index >= list->item_count) { - return NULL; - } - - // Return a pointer to the item at the given index. - return list->items[index]; -} - -size_t -pdc_list_size(PDC_LIST *list) -{ - if (list == NULL) { - return 0; - } - - // Return the number of items in the list. - return list->item_count; -} - -void -pdc_list_set_expansion_factor(PDC_LIST *list, double expansion_factor) -{ - if (list == NULL) { - return; - } - - // Set the new expansion factor for the list. - list->expansion_factor = expansion_factor; -} - -double -pdc_list_get_expansion_factor(PDC_LIST *list) -{ - if (list == NULL) { - return 0; - } - - // Return the current expansion factor for the list. - return list->expansion_factor; -} - -PDC_LIST_ITERATOR * -pdc_list_iterator_new(PDC_LIST *list) -{ - if (list == NULL) { - return NULL; - } - - // Allocate memory for the iterator struct. - PDC_LIST_ITERATOR *iterator = (PDC_LIST_ITERATOR *)malloc(sizeof(PDC_LIST_ITERATOR)); - if (iterator == NULL) { - return NULL; - } - - // Initialize the iterator fields. - iterator->list = list; - iterator->index = 0; - - return iterator; -} - -void -pdc_list_iterator_destroy(PDC_LIST_ITERATOR *iterator) -{ - if (iterator == NULL) { - return; - } - - // Free the iterator struct. - free(iterator); -} - -void * -pdc_list_iterator_next(PDC_LIST_ITERATOR *iterator) -{ - if (iterator == NULL) { - return NULL; - } - - // Return the next item in the list. - return pdc_list_get(iterator->list, iterator->index++); -} - -int -pdc_list_iterator_has_next(PDC_LIST_ITERATOR *iterator) -{ - if (iterator == NULL) { - return 0; - } - - // Return true if there are more items in the list. - return iterator->index < pdc_list_size(iterator->list); -} \ No newline at end of file diff --git a/tools/llsm/pdc_list.h b/tools/llsm/pdc_list.h deleted file mode 100644 index aa71e6124..000000000 --- a/tools/llsm/pdc_list.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef PDC_LIST_H -#define PDC_LIST_H - -#include - -/** - * A generic list data structure that stores a variable number of items of any type. - */ -typedef struct { - void **items; // Pointer to the array of items. - size_t item_count; // Number of items in the list. - size_t capacity; // Capacity of the array of items. - double expansion_factor; // Factor by which the capacity is expanded. -} PDC_LIST; - -/** - * A generic iterator for iterating over the items in a PDC_LIST. - */ -typedef struct { - PDC_LIST *list; // The list being iterated over. - size_t index; // The index of the next item to be returned. -} PDC_LIST_ITERATOR; - -/** - * Creates a new PDC_LIST with default initial capacity 100 and default expansion factor 2.0. - * @return A pointer to the new PDC_LIST. - */ -PDC_LIST *pdc_list_new(); - -/** - * Creates a new PDC_LIST with the given initial capacity and expansion factor. - * @param initial_capacity The initial capacity of the list. - * @param expansion_factor The factor by which the capacity is expanded when the list is full. - * - * @return A pointer to the new PDC_LIST. - */ -PDC_LIST *pdc_list_create(size_t initial_capacity, double expansion_factor); - -/** - * Destroys the given PDC_LIST and frees all allocated memory. - * @param list The PDC_LIST to destroy. - */ -void pdc_list_destroy(PDC_LIST *list); - -/** - * Adds the given item to the end of the given PDC_LIST. - * @param list The PDC_LIST to add the item to. - * @param item The item to add to the PDC_LIST. - * - */ -void pdc_list_add(PDC_LIST *list, void *item); - -/** - * Gets the item at the given index in the given PDC_LIST. - * @param list The PDC_LIST to get the item from. - * @param index The index of the item to get. - * - * @return A pointer to the item at the given index. - */ -void *pdc_list_get(PDC_LIST *list, size_t index); - -/** - * Sets the item at the given index in the given PDC_LIST. - * @param list The PDC_LIST to set the item in. - * - * @return The number of items in the list. - */ -size_t pdc_list_size(PDC_LIST *list); - -/** - * Sets the expansion factor for the given PDC_LIST. - * @param list The PDC_LIST to set the expansion factor for. - * @param expansion_factor The factor by which the capacity is expanded when the list is full. - */ -void pdc_list_set_expansion_factor(PDC_LIST *list, double expansion_factor); - -/** - * Gets the expansion factor for the given PDC_LIST. - * @param list The PDC_LIST to get the expansion factor for. - */ -double pdc_list_get_expansion_factor(PDC_LIST *list); - -/** - * Creates a new PDC_LIST_ITERATOR for the given PDC_LIST. - * @param list The PDC_LIST to create the iterator for. - * @return A pointer to the new PDC_LIST_ITERATOR. - */ -PDC_LIST_ITERATOR *pdc_list_iterator_new(PDC_LIST *list); - -/** - * Destroys the given PDC_LIST_ITERATOR and frees all allocated memory. - * @param iterator The PDC_LIST_ITERATOR to destroy. - */ -void pdc_list_iterator_destroy(PDC_LIST_ITERATOR *iterator); - -/** - * Returns the next item in the PDC_LIST_ITERATOR. - * @param iterator The PDC_LIST_ITERATOR to get the next item from. - * @return A pointer to the next item in the PDC_LIST_ITERATOR. - */ -void *pdc_list_iterator_next(PDC_LIST_ITERATOR *iterator); - -/** - * Returns true if the PDC_LIST_ITERATOR has more items. - * @param iterator The PDC_LIST_ITERATOR to check. - * @return True if the PDC_LIST_ITERATOR has more items. - */ -int pdc_list_iterator_has_next(PDC_LIST_ITERATOR *iterator); - -#endif // PDC_LIST_H \ No newline at end of file diff --git a/tools/llsm_importer.c b/tools/llsm_importer.c deleted file mode 100644 index ea5097278..000000000 --- a/tools/llsm_importer.c +++ /dev/null @@ -1,392 +0,0 @@ -#include -#include -#include -#include -#include - -#ifndef ENABLE_MPI -#define ENABLE_MPI -#endif - -#ifdef ENABLE_MPI -#include "mpi.h" -// #undef ENABLE_MPI -#endif - -#include "pdc.h" -// #include "pdc_client_server_common.h" -// #include "pdc_client_connect.h" - -#include "llsm/parallelReadTiff.h" -#include "llsm/pdc_list.h" -#include "llsm/csvReader.h" -#include - -typedef struct llsm_importer_args_t { - char * directory_path; - csv_header_t *csv_header; -} llsm_importer_args_t; - -int rank = 0, size = 1; - -pdcid_t pdc_id_g = 0, cont_prop_g = 0, cont_id_g = 0, obj_prop_g = 0; -struct timespec ts; - -double -getDoubleTimestamp() -{ - clock_gettime(CLOCK_MONOTONIC, &ts); - double timestamp = (double)ts.tv_sec + (double)ts.tv_nsec / 1e9; - return timestamp; -} - -int -parse_console_args(int argc, char *argv[], char **file_name) -{ - int c, parse_code = -1; - - while ((c = getopt(argc, argv, "f:")) != -1) { - switch (c) { - case 'f': - *file_name = optarg; - parse_code = 0; - break; - default: - fprintf(stderr, "Usage: %s [-f filename]\n", argv[0]); - parse_code = -1; - exit(EXIT_FAILURE); - } - } - return parse_code; -} - -void -import_to_pdc(image_info_t *image_info, csv_cell_t *fileName_cell) -{ - double duration, start; - - start = getDoubleTimestamp(); // start timing the operation - - obj_prop_g = PDCprop_create(PDC_OBJ_CREATE, pdc_id_g); - - psize_t ndims = 3; - uint64_t offsets[3] = {0, 0, 0}; - // FIXME: we should support uint64_t. - uint64_t dims[3] = {image_info->x, image_info->y, image_info->z}; - - // psize_t ndims = 1; - // uint64_t offsets[1] = {0}; - // // FIXME: we should support uint64_t. - // uint64_t dims[1] = {image_info->x * image_info->y * image_info->z}; - - // FIXME: we should change the ndims parameter to psize_t type. - PDCprop_set_obj_dims(obj_prop_g, (PDC_int_t)ndims, dims); - pdc_var_type_t pdc_type = PDC_UNKNOWN; - switch (image_info->bits) { - case 8: - pdc_type = PDC_UINT8; - break; - case 16: - pdc_type = PDC_UINT16; - break; - case 32: - pdc_type = PDC_FLOAT; - break; - case 64: - pdc_type = PDC_DOUBLE; - break; - default: - printf("Error: unsupported data type.\n"); - exit(-1); - } - PDCprop_set_obj_type(obj_prop_g, pdc_type); - PDCprop_set_obj_time_step(obj_prop_g, 0); - PDCprop_set_obj_user_id(obj_prop_g, getuid()); - PDCprop_set_obj_app_name(obj_prop_g, "LLSM"); - - // uint64_t *offsets = (uint64_t *)malloc(sizeof(uint64_t) * ndims); - // uint64_t *num_bytes = (uint64_t *)malloc(sizeof(uint64_t) * ndims); - // for (int i = 0; i < ndims; i++) { - // offsets[i] = 0; - // num_bytes[i] = dims[i] * image_info->bits / 8; - // } - - // create object - // FIXME: There are many attributes currently in one file name, - // and we should do some research to see what would be a good object name for each image. - pdcid_t cur_obj_g = PDCobj_create(cont_id_g, fileName_cell->field_value, obj_prop_g); - - // write data to object - pdcid_t local_region = PDCregion_create(ndims, offsets, dims); - pdcid_t remote_region = PDCregion_create(ndims, offsets, dims); - pdcid_t transfer_request = - PDCregion_transfer_create(image_info->tiff_ptr, PDC_WRITE, cur_obj_g, local_region, remote_region); - PDCregion_transfer_start(transfer_request); - PDCregion_transfer_wait(transfer_request); - - duration = getDoubleTimestamp() - start; // end timing the operation and calculate duration in nanoseconds - - printf("[Rank %4d] Region_Transfer %s_[%d_Bytes] Done! Time taken: %.4f seconds\n", rank, - fileName_cell->field_value, image_info->tiff_size, duration); - - // add metadata tags based on the csv row - csv_cell_t *cell = fileName_cell; - while (cell != NULL) { - char *field_name = cell->header->field_name; - char data_type = cell->header->field_type; - char *field_value = cell->field_value; - switch (data_type) { - case 'i': - int ivalue = atoi(field_value); - PDCobj_put_tag(cur_obj_g, field_name, &ivalue, PDC_INT, sizeof(int)); - break; - case 'f': - double fvalue = atof(field_value); - PDCobj_put_tag(cur_obj_g, field_name, &fvalue, PDC_DOUBLE, sizeof(double)); - break; - case 's': - PDCobj_put_tag(cur_obj_g, field_name, field_value, PDC_STRING, strlen(field_value)); - break; - default: - break; - } - cell = cell->next; - } - - // add extra metadata tags based on the image_info struct - PDCobj_put_tag(cur_obj_g, "x", &(image_info->x), PDC_UINT64, sizeof(uint64_t)); - PDCobj_put_tag(cur_obj_g, "y", &(image_info->y), PDC_UINT64, sizeof(uint64_t)); - PDCobj_put_tag(cur_obj_g, "z", &(image_info->z), PDC_UINT64, sizeof(uint64_t)); - PDCobj_put_tag(cur_obj_g, "bits", &(image_info->bits), PDC_UINT64, sizeof(uint64_t)); - PDCobj_put_tag(cur_obj_g, "startSlice", &(image_info->startSlice), PDC_UINT64, sizeof(uint64_t)); - PDCobj_put_tag(cur_obj_g, "stripeSize", &(image_info->stripeSize), PDC_UINT64, sizeof(uint64_t)); - PDCobj_put_tag(cur_obj_g, "is_imageJ", &(image_info->is_imageJ), PDC_UINT64, sizeof(uint64_t)); - PDCobj_put_tag(cur_obj_g, "imageJ_Z", &(image_info->imageJ_Z), PDC_UINT64, sizeof(uint64_t)); - - // close object - PDCobj_close(cur_obj_g); - - // get timing - duration = getDoubleTimestamp() - start; // end timing the operation calculate duration in nanoseconds - - printf("[Rank %4d] Create_object %s Done! Time taken: %.4f seconds\n", rank, fileName_cell->field_value, - duration); - - // free memory - // free(offsets); - // free(num_bytes); - // PDCregion_close(local_region); - // PDCregion_close(remote_region); - // PDCregion_transfer_close(transfer_request); - PDCprop_close(obj_prop_g); -} - -void -on_csv_row(csv_row_t *row, llsm_importer_args_t *llsm_args) -{ - csv_print_row(row, 1); - - char *dirname = strdup(llsm_args->directory_path); - char filepath[256]; - // calling tiff loading process. - image_info_t *image_info = NULL; - int i = 0; - double duration, start; - // Filepath,Filename,StageX_um_,StageY_um_,StageZ_um_,ObjectiveX_um_,ObjectiveY_um_,ObjectiveZ_um_ - - // get the file name from the csv row - csv_cell_t *fileName_cell = csv_get_field_value_by_name(row, llsm_args->csv_header, "Filename"); - - // check if the path ends with a forward slash - if (dirname[strlen(dirname) - 1] != '/') { - strcat(dirname, "/"); // add a forward slash to the end of the path - } - - strcpy(filepath, dirname); // copy the directory path to the file path - strcat(filepath, fileName_cell->field_value); // concatenate the file name to the file path - - start = getDoubleTimestamp(); // start timing the operation - - parallel_TIFF_load(filepath, 1, NULL, &image_info); - - duration = getDoubleTimestamp() - start; // end timing the operation and calculate duration in nanoseconds - - printf("[Rank %4d] Read %s Done! Time taken: %.4f seconds\n", rank, filepath, duration); - - if (image_info == NULL || image_info->tiff_ptr == NULL) { - return; - } - - printf("first few bytes "); - for (i = 0; i < 10; i++) { - printf("%d ", ((uint8_t *)image_info->tiff_ptr)[i]); - } - printf("\n"); - - // import the image to PDC - import_to_pdc(image_info, fileName_cell); - - // free the image info - free(image_info->tiff_ptr); - free(image_info); - free(dirname); -} - -void -read_txt(char *txtFileName, PDC_LIST *list, int *max_row_length) -{ - FILE *file = fopen(txtFileName, "r"); - - int row_length = 0; - - if (file == NULL) { - printf("Error: could not open file %s\n", txtFileName); - return; - } - char buffer[1024]; - // Read the lines of the file - while (fgets(buffer, sizeof(buffer), file)) { - pdc_list_add(list, strdup(buffer)); - if (row_length < strlen(buffer)) { - row_length = strlen(buffer); - } - } - - fclose(file); - - // Find the maximum row length - *max_row_length = row_length + 5; -} - -int -main(int argc, char *argv[]) -{ - -#ifdef ENABLE_MPI - MPI_Init(&argc, &argv); - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &size); -#endif - - char * file_name = NULL; - PDC_LIST * list = pdc_list_new(); - char * csv_line = NULL; - int num_row_read = 0; - csv_header_t * csv_header = NULL; - csv_row_t * csv_row = NULL; - llsm_importer_args_t *llsm_args = NULL; - int bcast_count = 512; - double duration = 0, start = 0; - char csv_field_types[] = {'s', 's', 'f', 'f', 'f', 'f', 'f', 'f'}; - // parse console argument - int parse_code = parse_console_args(argc, argv, &file_name); - if (parse_code) { - return parse_code; - } - char *directory_path = dirname(strdup(file_name)); - - // print file name for validating purpose - printf("Filename: %s\n", file_name ? file_name : "(none)"); - printf("Directory: %s\n", directory_path ? directory_path : "(none)"); - - // create a pdc - pdc_id_g = PDCinit("pdc"); - - // create a container property - cont_prop_g = PDCprop_create(PDC_CONT_CREATE, pdc_id_g); - if (cont_prop_g <= 0) - printf("Fail to create container property @ line %d!\n", __LINE__); - - // create a container - cont_id_g = PDCcont_create("c1", cont_prop_g); - if (cont_id_g <= 0) - printf("Fail to create container @ line %d!\n", __LINE__); - - // Rank 0 reads the filename list and distribute data to other ranks - if (rank == 0) { - read_txt(file_name, list, &bcast_count); - // print bcast_count - printf("bcast_count: %d \n", bcast_count); - -#ifdef ENABLE_MPI - // broadcast the number of lines - int num_lines = pdc_list_size(list); - MPI_Bcast(&num_lines, 1, MPI_INT, 0, MPI_COMM_WORLD); - // broadcast the bcast_count - MPI_Bcast(&bcast_count, 1, MPI_INT, 0, MPI_COMM_WORLD); - // broadcast the file names - PDC_LIST_ITERATOR *iter = pdc_list_iterator_new(list); - while (pdc_list_iterator_has_next(iter)) { - char *csv_line = (char *)pdc_list_iterator_next(iter); - MPI_Bcast(csv_line, bcast_count, MPI_CHAR, 0, MPI_COMM_WORLD); - } -#endif - } - else { -#ifdef ENABLE_MPI - // other ranks receive the number of files - int num_lines; - MPI_Bcast(&num_lines, 1, MPI_INT, 0, MPI_COMM_WORLD); - // receive the bcast_count - MPI_Bcast(&bcast_count, 1, MPI_INT, 0, MPI_COMM_WORLD); - // receive the file names - int i; - for (i = 0; i < num_lines; i++) { - csv_line = (char *)malloc(bcast_count * sizeof(char)); - MPI_Bcast(csv_line, bcast_count, MPI_CHAR, 0, MPI_COMM_WORLD); - pdc_list_add(list, csv_line); - } -#endif - } - // parse the csv - csv_table_t *csv_table = csv_parse_list(list, csv_field_types); - if (csv_table == NULL) { - printf("Fail to parse csv file @ line %d!\n", __LINE__); - return -1; - } - llsm_args = (llsm_importer_args_t *)malloc(sizeof(llsm_importer_args_t)); - llsm_args->directory_path = directory_path; - llsm_args->csv_header = csv_table->first_header; - -#ifdef ENABLE_MPI - MPI_Barrier(MPI_COMM_WORLD); - start = MPI_Wtime(); -#else - start = getDoubleTimestamp(); -#endif - // go through the csv table - csv_row_t *current_row = csv_table->first_row; - while (current_row != NULL) { - if (num_row_read % size == rank) { - on_csv_row(current_row, llsm_args); - } - num_row_read++; - current_row = current_row->next; - } - -#ifdef ENABLE_MPI - MPI_Barrier(MPI_COMM_WORLD); - duration = MPI_Wtime() - start; -#else - duration = getDoubleTimestamp() - start; -#endif - - if (rank == 0) { - printf("[Completion Time] LLSM IMPORTER FINISHES! Time taken: %.4f seconds\n", rank, duration); - } - // free memory for csv table - csv_free_table(csv_table); - - // close the container - PDCcont_close(cont_id_g); - // close the container property - PDCprop_close(cont_prop_g); - // close the pdc - PDCclose(pdc_id_g); - -#ifdef ENABLE_MPI - MPI_Finalize(); -#endif - - return 0; -}