diff --git a/include/HYPREDRV.h b/include/HYPREDRV.h index d1712b6..15b1fb4 100644 --- a/include/HYPREDRV.h +++ b/include/HYPREDRV.h @@ -177,7 +177,7 @@ HYPREDRV_Destroy(HYPREDRV_t*); * * Example Usage: * @code - * uint32_t errorCode = HYPREDRV_PrintLibInfo(); + * uint32_t errorCode = HYPREDRV_PrintLibInfo(comm); * if (errorCode != 0) { * const char* errorDescription = HYPREDRV_ErrorCodeDescribe(errorCode); * printf("%s\n", errorDescription); @@ -187,7 +187,24 @@ HYPREDRV_Destroy(HYPREDRV_t*); */ HYPREDRV_EXPORT_SYMBOL uint32_t -HYPREDRV_PrintLibInfo(void); +HYPREDRV_PrintLibInfo(MPI_Comm comm); + +/** + * @brief Print system information. + * + * Example Usage: + * @code + * uint32_t errorCode = HYPREDRV_PrintSystemInfo(comm); + * if (errorCode != 0) { + * const char* errorDescription = HYPREDRV_ErrorCodeDescribe(errorCode); + * printf("%s\n", errorDescription); + * // Handle error + * } + * @endcode + */ + +HYPREDRV_EXPORT_SYMBOL uint32_t +HYPREDRV_PrintSystemInfo(MPI_Comm comm); /** * @brief Print library information at exit. @@ -201,7 +218,7 @@ HYPREDRV_PrintLibInfo(void); * * Example Usage: * @code - * uint32_t errorCode = HYPREDRV_PrintExitInfo(argv[0]); + * uint32_t errorCode = HYPREDRV_PrintExitInfo(comm, argv[0]); * if (errorCode != 0) { * const char* errorDescription = HYPREDRV_ErrorCodeDescribe(errorCode); * printf("%s\n", errorDescription); @@ -211,7 +228,7 @@ HYPREDRV_PrintLibInfo(void); */ HYPREDRV_EXPORT_SYMBOL uint32_t -HYPREDRV_PrintExitInfo(const char*); +HYPREDRV_PrintExitInfo(MPI_Comm comm, const char*); /** * @brief Parse input arguments for a HYPREDRV object. diff --git a/include/info.h b/include/info.h index 71f7488..dd92667 100644 --- a/include/info.h +++ b/include/info.h @@ -8,6 +8,7 @@ #ifndef INFO_HEADER #define INFO_HEADER +#include #include #include #include "HYPRE.h" @@ -18,7 +19,8 @@ *--------------------------------------------------------------------------*/ void PrintUsage(const char*); -void PrintLibInfo(void); -void PrintExitInfo(const char*); +void PrintLibInfo(MPI_Comm); +void PrintSystemInfo(MPI_Comm); +void PrintExitInfo(MPI_Comm, const char*); #endif /* INFO_HEADER */ diff --git a/src/HYPREDRV.c b/src/HYPREDRV.c index c7f59e0..110e289 100644 --- a/src/HYPREDRV.c +++ b/src/HYPREDRV.c @@ -147,9 +147,21 @@ HYPREDRV_Destroy(HYPREDRV_t *obj_ptr) *-----------------------------------------------------------------------------*/ uint32_t -HYPREDRV_PrintLibInfo(void) +HYPREDRV_PrintLibInfo(MPI_Comm comm) { - PrintLibInfo(); + PrintLibInfo(comm); + + return ErrorCodeGet(); +} + +/*----------------------------------------------------------------------------- + * HYPREDRV_PrintSystemInfo + *-----------------------------------------------------------------------------*/ + +uint32_t +HYPREDRV_PrintSystemInfo(MPI_Comm comm) +{ + PrintSystemInfo(comm); return ErrorCodeGet(); } @@ -159,9 +171,9 @@ HYPREDRV_PrintLibInfo(void) *-----------------------------------------------------------------------------*/ uint32_t -HYPREDRV_PrintExitInfo(const char *argv0) +HYPREDRV_PrintExitInfo(MPI_Comm comm, const char *argv0) { - PrintExitInfo(argv0); + PrintExitInfo(comm, argv0); return ErrorCodeGet(); } diff --git a/src/containers.c b/src/containers.c index ff1cc5b..fedc4e5 100644 --- a/src/containers.c +++ b/src/containers.c @@ -262,7 +262,7 @@ IntArrayUnique(MPI_Comm comm, IntArray *int_array) } } } - MPI_Bcast(&int_array->g_unique_size, 1, MPI_INT, 0, comm); + MPI_Bcast(&int_array->g_unique_size, 1, MPI_UNSIGNED_LONG, 0, comm); int_array->g_unique_data = (int*) calloc(int_array->g_unique_size, sizeof(int)); /* Compute global unique data */ diff --git a/src/info.c b/src/info.c index e6e2ba5..b011475 100644 --- a/src/info.c +++ b/src/info.c @@ -5,41 +5,528 @@ * SPDX-License-Identifier: MIT ******************************************************************************/ +#include +#include +#include +#include #include "info.h" #include "HYPRE_config.h" +#if defined(HYPRE_USING_OPENMP) +#include +#endif + +#if defined(__APPLE__) +#include +#include +#include +#else +#include +#define __USE_GNU +#include +#endif + +#ifndef STRINGIFY +#define STRINGIFY(x) #x +#endif +#ifndef TOSTRING +#define TOSTRING(x) STRINGIFY(x) +#endif + +#ifndef __APPLE__ + +/*-------------------------------------------------------------------------- + * dlpi_callback + * + * Linux: Use dl_iterate_phdr to list dynamic libraries + *--------------------------------------------------------------------------*/ + +int +dlpi_callback(struct dl_phdr_info *info, size_t size, void *data) +{ + if (info->dlpi_name && info->dlpi_name[0]) + { + const char* filename = strrchr(info->dlpi_name, '/'); + filename = filename ? filename + 1 : info->dlpi_name; + printf(" %s => %s (0x%lx)\n", filename, info->dlpi_name, info->dlpi_addr); + } + return 0; +} + +#endif + +/*-------------------------------------------------------------------------- + * PrintSystemInfo + *--------------------------------------------------------------------------*/ + +void +PrintSystemInfo(MPI_Comm comm) +{ + int myid, nprocs; + char hostname[256]; + double bytes_to_GB = (double) (1 << 30); + double MB_to_GB = (double) (1 << 10); + size_t total, used, free; + int gcount; + FILE *fp = NULL; + char buffer[32768]; + + MPI_Comm_rank(comm, &myid); + MPI_Comm_size(comm, &nprocs); + + /* Array to gather all hostnames */ + char allHostnames[nprocs * 256]; + + /* Get the hostname for this process */ + gethostname(hostname, sizeof(hostname)); + + /* Gather all hostnames to all processes */ + MPI_Allgather(hostname, 256, MPI_CHAR, allHostnames, 256, MPI_CHAR, MPI_COMM_WORLD); + + if (!myid) + { + printf("================================ System Information ================================\n\n"); + + // 1. CPU cores and model + int numPhysicalCPUs = 0; + int physicalCPUSeen = 0; + int numCPUs; + char cpuModels[8][256]; + char gpuInfo[256] = "Unknown"; + + /* Count unique hostnames */ + int numNodes = 0; + for (int i = 0; i < nprocs; i++) + { + int isUnique = 1; + for (int j = 0; j < i; j++) + { + if (strncmp(&allHostnames[i * 256], &allHostnames[j * 256], 256) == 0) + { + isUnique = 0; + break; + } + } + if (isUnique) + { + numNodes++; + } + } + +#if defined(__APPLE__) + size_t msize = sizeof(numCPUs); + sysctlbyname("hw.ncpu", &numCPUs, &msize, NULL, 0); + + msize = sizeof(numPhysicalCPUs); + sysctlbyname("hw.packages", &numPhysicalCPUs, &msize, NULL, 0); + + for (int i = 0; i < numPhysicalCPUs; i++) + { + msize = sizeof(cpuModels[i]); + sysctlbyname("machdep.cpu.brand_string", &cpuModels[i], &msize, NULL, 0); + } +#else + fp = fopen("/proc/cpuinfo", "r"); + if (fp != NULL) + { + while (fgets(buffer, sizeof(buffer), fp)) + { + if (strncmp(buffer, "physical id", 11) == 0) + { + int physicalID = atoi(strchr(buffer, ':') + 2); + if (physicalID >= 0 && physicalID < 8) + { + unsigned long long mask = 1ULL << physicalID; + if (!(physicalCPUSeen & mask)) + { + physicalCPUSeen |= mask; + numPhysicalCPUs++; + } + } + } + + if (strncmp(buffer, "model name", 10) == 0) + { + int physicalID = numPhysicalCPUs - 1; + if (physicalID >= 0 && physicalID < 8) + { + char* model = strchr(buffer, ':') + 2; + strncpy(cpuModels[physicalID], model, + sizeof(cpuModels[physicalID]) - 1); + cpuModels[physicalID][strlen(cpuModels[physicalID]) - 1] = '\0'; + } + } + } + fclose(fp); + + if (numPhysicalCPUs == 0) + { + fp = popen("lscpu | grep 'Socket(s)' | awk '{print $2}'", "r"); + if (fp != NULL) + { + if (fgets(buffer, sizeof(buffer), fp) != NULL) + { + numPhysicalCPUs = atoi(buffer); + } + pclose(fp); + } + + fp = popen("lscpu | grep 'Model name:' | sed 's/Model name:\\s*//'", "r"); + if (fp != NULL) + { + if (fgets(buffer, sizeof(buffer), fp) != NULL) + { + buffer[strcspn(buffer, "\n")] = '\0'; + for (int i = 0; i < numPhysicalCPUs; i++) + { + strncpy(cpuModels[i], buffer, sizeof(cpuModels[i]) - 1); + cpuModels[i][sizeof(cpuModels[i]) - 1] = '\0'; + } + } + pclose(fp); + } + } + } + + numCPUs = sysconf(_SC_NPROCESSORS_ONLN); +#endif + if (strlen(gpuInfo) == 0) + { + strncpy(gpuInfo, "Unknown", 8 * sizeof(char)); + } + + printf("Processing Units\n"); + printf("-----------------\n"); + printf("Number of Nodes : %d\n", numNodes); + printf("Number of Processors : %d\n", numPhysicalCPUs); + printf("Number of CPU threads : %d\n", numCPUs); + printf("Tot. # of Processors : %lld\n", (long long) numNodes * (long long) numPhysicalCPUs); + printf("Tot. # of CPU threads : %lld\n", (long long) numNodes * (long long) numCPUs); + for (int i = 0; i < numPhysicalCPUs; i++) + { + printf("CPU Model #%d : %s\n", i, cpuModels[i]); + } + +#ifndef __APPLE__ + gcount = 0; + fp = NULL; + if (system("command -v lspci > /dev/null 2>&1") == 0) + { + fp = popen("lspci | grep -Ei 'vga|3d|2d|display|accel'", "r"); + } + if (fp != NULL) + { + while (fgets(buffer, sizeof(buffer), fp) != NULL) + { + /* Skip onboard server graphics */ + if (strstr(buffer, "Matrox") != NULL) { continue; } + if (strstr(buffer, "ASPEED") != NULL) { continue; } + if (strstr(buffer, "Nuvoton") != NULL) { continue; } + + char *start = strstr(buffer, "VGA compatible controller"); + if (!start) start = strstr(buffer, "3D controller"); + if (!start) start = strstr(buffer, "2D controller"); + if (!start) start = strstr(buffer, "Display controller"); + if (!start) start = strstr(buffer, "Processing accelerators"); + + if (start) + { + /* Adjust the strncpy depending on which controller type was found */ + const char *controller_type = "VGA compatible controller: "; + if (strstr(buffer, "3D controller") != NULL) + { + controller_type = "3D controller: "; + } + else if (strstr(buffer, "2D controller") != NULL) + { + controller_type = "2D controller: "; + } + else if (strstr(buffer, "Display controller") != NULL) + { + controller_type = "Display controller: "; + } + else if (strstr(buffer, "Processing accelerators") != NULL) + { + controller_type = "Processing accelerators: "; + } + + strncpy(gpuInfo, start + strlen(controller_type), sizeof(gpuInfo) - 1); + gpuInfo[sizeof(gpuInfo) - 1] = '\0'; + + /* Remove newline if present */ + size_t len = strlen(gpuInfo); + if (len > 0 && gpuInfo[len - 1] == '\n') + { + gpuInfo[len - 1] = '\0'; + } + + printf("GPU Model #%d : %s\n", gcount++, gpuInfo); + } + else + { + strncpy(gpuInfo, buffer, sizeof(gpuInfo) - 1); + gpuInfo[sizeof(gpuInfo) - 1] = '\0'; + } + } + pclose(fp); + } + else if (system("command -v nvidia-smi > /dev/null 2>&1") == 0) + { + fp = popen("nvidia-smi --query-gpu=name --format=csv,noheader", "r"); + if (fp != NULL) + { + while (fgets(buffer, sizeof(buffer), fp) != NULL) + { + printf("GPU Model #%d : %s", gcount++, buffer); + } + pclose(fp); + } + } + gcount = 0; +#endif + printf("\n"); + + // 2. Memory available and used + printf("Memory Information (Used/Total)\n"); + printf("--------------------------------\n"); +#if defined(__APPLE__) + size_t memSizeLen = sizeof(total); + sysctlbyname("hw.memsize", &total, &memSizeLen, NULL, 0); + + mach_msg_type_number_t count = HOST_VM_INFO_COUNT; + vm_statistics_data_t vmstat; + if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat, &count) == KERN_SUCCESS) + { + free = (size_t) vmstat.free_count * sysconf(_SC_PAGESIZE); + used = total - free; + + printf("CPU RAM : %6.2f / %6.2f (%5.2f %%) GB\n", + (double) used / bytes_to_GB, + (double) total / bytes_to_GB, + 100.0 * (total - used) / (double) total); + } +#else + struct sysinfo info; + if (sysinfo(&info) == 0) + { + printf("CPU RAM : %6.2f / %6.2f (%5.2f %%) GB\n", + (double) (info.totalram - info.freeram) * info.mem_unit / bytes_to_GB, + (double) info.totalram * info.mem_unit / bytes_to_GB, + 100.0 * (info.totalram - info.freeram) / (double) info.totalram); + } +#endif + + /* NVIDIA GPU Memory Information */ + fp = NULL; + if (system("command -v nvidia-smi > /dev/null 2>&1") == 0) + { + fp = popen("nvidia-smi --query-gpu=memory.total,memory.used --format=csv,noheader,nounits", "r"); + } + if (fp != NULL) + { + while (fgets(buffer, sizeof(buffer), fp) != NULL) + { + sscanf(buffer, "%ld, %ld", &total, &used); + printf("GPU RAM #%d : %6.2f / %6.2f (%5.2f %%) GB\n", + gcount++, + used / MB_to_GB, + total / MB_to_GB, + 100.0 * used / (double) total); + } + pclose(fp); + } + + /* AMD GPU Memory Information */ + fp = NULL; + if (system("command -v rocm-smi > /dev/null 2>&1") == 0) + { + fp = popen("rocm-smi --showmeminfo vram --json", "r"); + } + if (fp != NULL) + { + fread(buffer, sizeof(char), sizeof(buffer) - 1, fp); + buffer[sizeof(buffer) - 1] = '\0'; + pclose(fp); + + const char *vram_total_str = "\"VRAM Total Memory (B)\": \""; + const char *vram_used_str = "\"VRAM Total Used Memory (B)\": \""; + const char *ptr = buffer; + + while ((ptr = strstr(ptr, vram_total_str)) != NULL) + { + ptr += strlen(vram_total_str); + total = strtoll(ptr, NULL, 10); + + ptr = strstr(ptr, vram_used_str); + ptr += strlen(vram_used_str); + used = strtoll(ptr, NULL, 10); + + printf("GPU RAM #%d : %6.2f / %6.2f (%5.2f %%) GB\n", + gcount++, + used / bytes_to_GB, + total / bytes_to_GB, + 100.0 * used / (double) total); + } + } + + // 3. OS system info, release, version, machine + printf("\nOperating System\n"); + printf("-----------------\n"); + struct utsname sysinfo; + if (uname(&sysinfo) == 0) + { + printf("System Name : %s\n", sysinfo.sysname); + printf("Node Name : %s\n", sysinfo.nodename); + printf("Release : %s\n", sysinfo.release); + printf("Version : %s\n", sysinfo.version); + printf("Machine Architecture : %s\n\n", sysinfo.machine); + } + + // 4. Compilation Flags Information + printf("Compilation Information\n"); + printf("------------------------\n"); + printf("Date : %s at %s\n", __DATE__, __TIME__); + +#if defined(__OPTIMIZE__) + printf("Optimization : Enabled\n"); +#else + printf("Optimization : Disabled\n"); +#endif +#if defined(DEBUG) + printf("Debugging : Enabled\n"); +#else + printf("Debugging : Disabled\n"); +#endif +#if defined(__clang__) + printf("Compiler : Clang %d.%d.%d\n", __clang_major__, __clang_minor__, __clang_patchlevel__); +#elif defined(__INTEL_COMPILER) + printf("Compiler : Intel %d.%d\n", __INTEL_COMPILER / 100, (__INTEL_COMPILER % 100) / 10); +#elif defined(__GNUC__) + printf("Compiler : GCC %d.%d.%d\n", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); +#else + printf("Compiler : Unknown\n"); +#endif +#if defined(HYPRE_USING_OPENMP) && defined(_OPENMP) + printf("OpenMP : Supported (Version: %d)\n", _OPENMP); +#else + printf("OpenMP : Not used\n"); +#endif + printf("MPI library : "); +#if defined(CRAY_MPICH_VERSION) + printf("Cray MPI (Version: %s)\n", TOSTRING(CRAY_MPICH_VERSION)); +#elif defined(INTEL_MPI_VERSION) + printf("Intel MPI (Version: %s)\n", INTEL_MPI_VERSION); +#elif defined(__IBM_MPI__) + printf("IBM Spectrum MPI (Version: %d.%d.%d)\n", + __IBM_MPI_MAJOR_VERSION, + __IBM_MPI_MINOR_VERSION, + __IBM_MPI_RELEASE_VERSION); +#elif defined(MVAPICH2_VERSION) + printf("MVAPICH2 (Version: %s)\n", MVAPICH2_VERSION); +#elif defined(MPICH_NAME) + printf("MPICH (Version: %s)\n", MPICH_VERSION); +#elif defined(OMPI_MAJOR_VERSION) + printf("OpenMPI (Version: %d.%d.%d)\n", OMPI_MAJOR_VERSION, OMPI_MINOR_VERSION, OMPI_RELEASE_VERSION); +#elif defined(SGI_MPI) + printf("SGI MPI\n"); +#else + printf("N/A\n"); +#endif +#if defined(__x86_64__) + printf("Target architecture : x86_64\n"); +#elif defined(__i386__) + printf("Target architecture : x86 (32-bit)\n"); +#elif defined(__aarch64__) + printf("Target architecture : ARM64\n"); +#elif defined(__arm__) + printf("Target architecture : ARM\n"); +#else + printf("Target architecture : Unknown\n"); +#endif +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + printf("Endianness : Little-endian\n"); +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + printf("Endianness : Big-endian\n"); +#else + printf("Endianness : Unknown\n"); +#endif + printf("\n"); + + // 5. Current working directory + printf("Current Working Directory\n"); + printf("--------------------------\n"); + char cwd[4096]; + if (getcwd(cwd, sizeof(cwd)) != NULL) + { + printf("%s\n\n", cwd); + } + + // 6. Dynamic libraries used + printf("Dynamic Libraries Loaded\n"); + printf("------------------------\n"); +#if defined(__APPLE__) + uint32_t dcount = _dyld_image_count(); + for (uint32_t i = 0; i < dcount; i++) + { + const char* name = _dyld_get_image_name(i); + const struct mach_header* header = _dyld_get_image_header(i); + const char* filename = strrchr(name, '/'); + + filename = filename ? filename + 1 : name; + printf(" %s => %s (0x%lx)\n", filename, name, (unsigned long)header); + } +#else + dl_iterate_phdr(dlpi_callback, NULL); +#endif + + printf("\n================================ System Information ================================\n\n"); + printf("Running on %d MPI rank%s\n", nprocs, nprocs > 1 ? "s" : ""); + + /* Number of OpenMP threads per rank used in hypre */ +#if defined(HYPRE_USING_OPENMP) && defined(_OPENMP) + int num_threads = omp_get_max_threads(); + printf("Running on %d OpenMP thread%s per MPI rank\n", num_threads, num_threads > 1 ? "s" : ""); +#endif + } +} /*-------------------------------------------------------------------------- * PrintLibInfo *--------------------------------------------------------------------------*/ void -PrintLibInfo(void) +PrintLibInfo(MPI_Comm comm) { + int myid; time_t t; struct tm *tm_info; char buffer[100]; - /* Get current time */ - time(&t); - tm_info = localtime(&t); + MPI_Comm_rank(comm, &myid); - /* Format and print the date and time */ - strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm_info); - printf("Date and time: %s\n", buffer); + if (!myid) + { + /* Get current time */ + time(&t); + tm_info = localtime(&t); - /* Print hypre info */ + /* Format and print the date and time */ + strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm_info); + printf("Date and time: %s\n", buffer); + + /* Print hypre info */ #if defined(HYPRE_DEVELOP_STRING) && defined(HYPRE_BRANCH_NAME) - printf("\nUsing HYPRE_DEVELOP_STRING: %s (%s)\n\n", - HYPRE_DEVELOP_STRING, HYPRE_BRANCH_NAME); + printf("\nUsing HYPRE_DEVELOP_STRING: %s (%s)\n\n", + HYPRE_DEVELOP_STRING, HYPRE_BRANCH_NAME); #elif defined(HYPRE_DEVELOP_STRING) && !defined(HYPRE_BRANCH_NAME) - printf("\nUsing HYPRE_DEVELOP_STRING: %s\n\n", - HYPRE_DEVELOP_STRING); + printf("\nUsing HYPRE_DEVELOP_STRING: %s\n\n", + HYPRE_DEVELOP_STRING); #elif defined(HYPRE_RELEASE_VERSION) - printf("\nUsing HYPRE_RELEASE_VERSION: %s\n\n", - HYPRE_RELEASE_VERSION); + printf("\nUsing HYPRE_RELEASE_VERSION: %s\n\n", + HYPRE_RELEASE_VERSION); #endif + } } /*-------------------------------------------------------------------------- @@ -47,17 +534,23 @@ PrintLibInfo(void) *--------------------------------------------------------------------------*/ void -PrintExitInfo(const char *argv0) +PrintExitInfo(MPI_Comm comm, const char *argv0) { + int myid; time_t t; struct tm *tm_info; char buffer[100]; - /* Get current time */ - time(&t); - tm_info = localtime(&t); + MPI_Comm_rank(comm, &myid); + + if (!myid) + { + /* Get current time */ + time(&t); + tm_info = localtime(&t); - /* Format and print the date and time */ - strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm_info); - printf("Date and time: %s\n\%s done!\n", buffer, argv0); + /* Format and print the date and time */ + strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm_info); + printf("Date and time: %s\n%s done!\n", buffer, argv0); + } } diff --git a/src/linsys.c b/src/linsys.c index dcdd16d..8587660 100644 --- a/src/linsys.c +++ b/src/linsys.c @@ -201,8 +201,8 @@ LinearSystemReadMatrix(MPI_Comm comm, LS_args *args, HYPRE_IJMatrix *matrix_ptr) "%.*s_%0*d/%.*s", (int) strlen(args->dirname), args->dirname, - args->digits_suffix, - args->init_suffix + ls_id, + (int) args->digits_suffix, + (int) args->init_suffix + ls_id, (int) strlen(args->matrix_filename), args->matrix_filename); } @@ -217,8 +217,8 @@ LinearSystemReadMatrix(MPI_Comm comm, LS_args *args, HYPRE_IJMatrix *matrix_ptr) "%.*s_%0*d", (int) strlen(args->matrix_basename), args->matrix_basename, - args->digits_suffix, - args->init_suffix + ls_id); + (int) args->digits_suffix, + (int) args->init_suffix + ls_id); } else { @@ -397,8 +397,8 @@ LinearSystemSetRHS(MPI_Comm comm, LS_args *args, HYPRE_IJMatrix mat, HYPRE_IJVec "%.*s_%0*d/%.*s", (int) strlen(args->dirname), args->dirname, - args->digits_suffix, - args->init_suffix + ls_id, + (int) args->digits_suffix, + (int) args->init_suffix + ls_id, (int) strlen(args->rhs_filename), args->rhs_filename); } @@ -413,8 +413,8 @@ LinearSystemSetRHS(MPI_Comm comm, LS_args *args, HYPRE_IJMatrix mat, HYPRE_IJVec "%.*s_%0*d", (int) strlen(args->rhs_basename), args->rhs_basename, - args->digits_suffix, - args->init_suffix + ls_id); + (int) args->digits_suffix, + (int) args->init_suffix + ls_id); } /* Read vector from file (Binary or ASCII) */ @@ -631,8 +631,8 @@ LinearSystemReadDofmap(MPI_Comm comm, LS_args *args, IntArray **dofmap_ptr) "%.*s_%0*d/%.*s", (int) strlen(args->dirname), args->dirname, - args->digits_suffix, - args->init_suffix + ls_id, + (int) args->digits_suffix, + (int) args->init_suffix + ls_id, (int) strlen(args->dofmap_filename), args->dofmap_filename); } @@ -647,8 +647,8 @@ LinearSystemReadDofmap(MPI_Comm comm, LS_args *args, IntArray **dofmap_ptr) "%.*s_%0*d", (int) strlen(args->dofmap_basename), args->dofmap_basename, - args->digits_suffix, - args->init_suffix + ls_id); + (int) args->digits_suffix, + (int) args->init_suffix + ls_id); } /* Destroy previous dofmap array */ diff --git a/src/main.c b/src/main.c index 2d255e4..8f96851 100644 --- a/src/main.c +++ b/src/main.c @@ -19,7 +19,7 @@ PrintUsage(const char *argv0) int main(int argc, char **argv) { MPI_Comm comm = MPI_COMM_WORLD; - int myid, nprocs, i, k; + int myid, i, k; HYPREDRV_t obj; /*----------------------------------------------------------- @@ -28,7 +28,6 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); MPI_Comm_rank(comm, &myid); - MPI_Comm_size(comm, &nprocs); HYPREDRV_Initialize(); HYPREDRV_Create(comm, &obj); @@ -42,8 +41,8 @@ int main(int argc, char **argv) * Print libraries/driver info *-----------------------------------------------------------*/ - if (!myid) HYPREDRV_PrintLibInfo(); - if (!myid) printf("Running on %d MPI rank%s\n", nprocs, nprocs > 1 ? "s" : ""); + HYPREDRV_PrintLibInfo(comm); + HYPREDRV_PrintSystemInfo(comm); /*----------------------------------------------------------- * Parse input parameters @@ -101,7 +100,7 @@ int main(int argc, char **argv) *-----------------------------------------------------------*/ if (!myid) HYPREDRV_StatsPrint(obj); - if (!myid) HYPREDRV_PrintExitInfo(argv[0]); + HYPREDRV_PrintExitInfo(comm, argv[0]); HYPREDRV_Destroy(&obj); HYPREDRV_Finalize(); diff --git a/src/matrix.c b/src/matrix.c index 120c26c..c3ad20a 100644 --- a/src/matrix.c +++ b/src/matrix.c @@ -84,7 +84,7 @@ IJMatrixReadMultipartBinary(const char *prefixname, } /* 3) Build IJMatrix */ - MPI_Scan(&nrows_sum, &nrows_offset, 1, MPI_UNSIGNED_LONG_LONG, MPI_SUM, comm); + MPI_Scan(&nrows_sum, &nrows_offset, 1, MPI_UNSIGNED_LONG, MPI_SUM, comm); ilower = (HYPRE_BigInt) (nrows_offset - nrows_sum); iupper = (HYPRE_BigInt) (ilower + nrows_sum - 1); @@ -100,7 +100,13 @@ IJMatrixReadMultipartBinary(const char *prefixname, { sprintf(filename, "%s.%05d.bin", prefixname, partids[part]); fp = fopen(filename, "rb"); - fread(header, sizeof(uint64_t), 11, fp) == 11; + if (fread(header, sizeof(uint64_t), 11, fp) != 11) + { + ErrorCodeSet(ERROR_FILE_UNEXPECTED_ENTRY); + ErrorMsgAdd("Could not read header from %s", filename); + fclose(fp); + return; + } /* Read row and column indices */ if (header[1] == sizeof(HYPRE_BigInt)) diff --git a/src/mgr.c b/src/mgr.c index e8cfb60..74a8108 100644 --- a/src/mgr.c +++ b/src/mgr.c @@ -416,6 +416,7 @@ MGRCreate(MGR_args *args, HYPRE_Solver *precon_ptr, HYPRE_Solver *csolver_ptr) HYPRE_Solver csolver; HYPRE_Solver frelax; HYPRE_Solver grelax; + HYPRE_Int *dofmap_data; IntArray *dofmap; HYPRE_Int num_dofs; HYPRE_Int num_dofs_last; @@ -460,10 +461,24 @@ MGRCreate(MGR_args *args, HYPRE_Solver *precon_ptr, HYPRE_Solver *csolver_ptr) } } + /* Set dofmap_data */ + if (sizeof(HYPRE_Int) == sizeof(int)) + { + dofmap_data = (HYPRE_Int*) dofmap->data; + } + else + { + dofmap_data = (HYPRE_Int*) malloc(dofmap->size * sizeof(HYPRE_Int)); + for (i = 0; i < dofmap->size; i++) + { + dofmap_data[i] = (HYPRE_Int) dofmap->data[i]; + } + } + /* Config preconditioner */ HYPRE_MGRCreate(&precon); HYPRE_MGRSetCpointsByPointMarkerArray(precon, num_dofs, num_levels - 1, - num_c_dofs, c_dofs, dofmap->data); + num_c_dofs, c_dofs, dofmap_data); HYPRE_MGRSetNonCpointsToFpoints(precon, args->non_c_to_f); HYPRE_MGRSetMaxIter(precon, args->max_iter); HYPRE_MGRSetTol(precon, args->tolerance); @@ -530,4 +545,8 @@ MGRCreate(MGR_args *args, HYPRE_Solver *precon_ptr, HYPRE_Solver *csolver_ptr) { free(c_dofs[lvl]); } + if ((void *) dofmap_data != (void *) dofmap->data) + { + free(dofmap_data); + } } diff --git a/src/vector.c b/src/vector.c index b9bea4d..719ec62 100644 --- a/src/vector.c +++ b/src/vector.c @@ -82,7 +82,7 @@ IJVectorReadMultipartBinary(const char *prefixname, } /* 3) Build IJVector */ - MPI_Scan(&nrows_sum, &nrows_offset, 1, MPI_UNSIGNED_LONG_LONG, MPI_SUM, comm); + MPI_Scan(&nrows_sum, &nrows_offset, 1, MPI_UNSIGNED_LONG, MPI_SUM, comm); ilower = (HYPRE_BigInt) (nrows_offset - nrows_sum); iupper = (HYPRE_BigInt) (ilower + nrows_sum - 1); @@ -96,7 +96,13 @@ IJVectorReadMultipartBinary(const char *prefixname, { sprintf(filename, "%s.%05d.bin", prefixname, partids[part]); fp = fopen(filename, "rb"); - fread(header, sizeof(uint64_t), 8, fp) == 8; + if (fread(header, sizeof(uint64_t), 8, fp) != 8) + { + ErrorCodeSet(ERROR_FILE_UNEXPECTED_ENTRY); + ErrorMsgAdd("Could not read header from %s", filename); + fclose(fp); + return; + } /* Read vector coefficients */ if (header[1] == sizeof(HYPRE_Complex))