diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt deleted file mode 100644 index ee3d39c..0000000 --- a/samples/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_subdirectory(ctest) -add_subdirectory(cpptest) -add_subdirectory(mpitest) diff --git a/samples/cpptest/CMakeLists.txt b/samples/cpptest/CMakeLists.txt index 4782bda..57feb21 100644 --- a/samples/cpptest/CMakeLists.txt +++ b/samples/cpptest/CMakeLists.txt @@ -1,10 +1,3 @@ -## C++ standard -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -## Compilation flags -add_compile_options(-Wall -Wextra -Werror -Wdouble-promotion -Wfloat-conversion -Wshadow) - -## Compile and link +## cpptest add_executable(cpptest main.cc) target_link_libraries(cpptest PRIVATE astaroth_core astaroth_utils) diff --git a/samples/cpptest/main.cc b/samples/cpptest/main.cc index e5387fd..1468e14 100644 --- a/samples/cpptest/main.cc +++ b/samples/cpptest/main.cc @@ -21,17 +21,18 @@ #include #include "astaroth.h" - -// From Astaroth Utils -#include "src/utils/config_loader.h" -#include "src/utils/memory.h" -#include "src/utils/verification.h" +#include "astaroth_utils.h" int main(void) { AcMeshInfo info; acLoadConfig(AC_DEFAULT_CONFIG, &info); + // Some real params must be calculated (for the MHD case) // TODO DANGEROUS + info.real_params[AC_inv_dsx] = (AcReal)(1.0) / info.real_params[AC_dsx]; + info.real_params[AC_inv_dsy] = (AcReal)(1.0) / info.real_params[AC_dsy]; + info.real_params[AC_inv_dsz] = (AcReal)(1.0) / info.real_params[AC_dsz]; + info.real_params[AC_cs2_sound] = info.real_params[AC_cs_sound] * info.real_params[AC_cs_sound]; // Alloc AcMesh model, candidate; @@ -42,17 +43,26 @@ main(void) acMeshRandomize(&model); acMeshApplyPeriodicBounds(&model); - //////////////////////////////////////////////////////////////////////////////////////////////// + // Verify that the mesh was loaded and stored correctly acInit(info); acLoad(model); acStore(&candidate); - acQuit(); - //////////////////////////////////////////////////////////////////////////////////////////////// - - // Verify and destroy acVerifyMesh(model, candidate); + + // Attempt to integrate and check max and min + printf("Integrating... "); + acIntegrate(FLT_EPSILON); + printf("Done.\nVTXBUF ranges after one integration step:\n"); + for (size_t i = 0; i < NUM_VTXBUF_HANDLES; ++i) + printf("\t%-15s... [%.3g, %.3g]\n", vtxbuf_names[i], + (double)acReduceScal(RTYPE_MIN, (VertexBufferHandle)i), + (double)acReduceScal(RTYPE_MAX, (VertexBufferHandle)i)); + + // Destroy + acQuit(); acMeshDestroy(&model); acMeshDestroy(&candidate); + puts("cpptest complete."); return EXIT_SUCCESS; } diff --git a/samples/ctest/CMakeLists.txt b/samples/ctest/CMakeLists.txt index 5e01f02..719dc24 100644 --- a/samples/ctest/CMakeLists.txt +++ b/samples/ctest/CMakeLists.txt @@ -1,9 +1,3 @@ -############################################## -## CMakeLists.txt for the C API test ## -############################################## - -set(CMAKE_C_STANDARD 11) -set(CMAKE_C_STANDARD_REQUIRED ON) - +## ctest add_executable(ctest main.c) target_link_libraries(ctest PRIVATE astaroth_core astaroth_utils) diff --git a/samples/ctest/main.c b/samples/ctest/main.c index 4b6bfc9..2b4f9c0 100644 --- a/samples/ctest/main.c +++ b/samples/ctest/main.c @@ -20,17 +20,18 @@ #include #include "astaroth.h" - -// From Astaroth Utils -#include "src/utils/config_loader.h" -#include "src/utils/memory.h" -#include "src/utils/verification.h" +#include "astaroth_utils.h" int main(void) { AcMeshInfo info; acLoadConfig(AC_DEFAULT_CONFIG, &info); + // Some real params must be calculated (for the MHD case) // TODO DANGEROUS + info.real_params[AC_inv_dsx] = (AcReal)(1.0) / info.real_params[AC_dsx]; + info.real_params[AC_inv_dsy] = (AcReal)(1.0) / info.real_params[AC_dsy]; + info.real_params[AC_inv_dsz] = (AcReal)(1.0) / info.real_params[AC_dsz]; + info.real_params[AC_cs2_sound] = info.real_params[AC_cs_sound] * info.real_params[AC_cs_sound]; // Alloc AcMesh model, candidate; @@ -41,17 +42,26 @@ main(void) acMeshRandomize(&model); acMeshApplyPeriodicBounds(&model); - //////////////////////////////////////////////////////////////////////////////////////////////// + // Verify that the mesh was loaded and stored correctly acInit(info); acLoad(model); acStore(&candidate); - acQuit(); - //////////////////////////////////////////////////////////////////////////////////////////////// - - // Verify and destroy acVerifyMesh(model, candidate); + + // Attempt to integrate and check max and min + printf("Integrating... "); + acIntegrate(FLT_EPSILON); + printf("Done.\nVTXBUF ranges after one integration step:\n"); + for (size_t i = 0; i < NUM_VTXBUF_HANDLES; ++i) + printf("\t%-15s... [%.3g, %.3g]\n", vtxbuf_names[i], // + (double)acReduceScal(RTYPE_MIN, i), // + (double)acReduceScal(RTYPE_MAX, i)); + + // Destroy + acQuit(); acMeshDestroy(&model); acMeshDestroy(&candidate); + puts("ctest complete."); return EXIT_SUCCESS; } diff --git a/samples/mpitest/CMakeLists.txt b/samples/mpitest/CMakeLists.txt index 3a606db..57da922 100644 --- a/samples/mpitest/CMakeLists.txt +++ b/samples/mpitest/CMakeLists.txt @@ -1,9 +1,3 @@ -############################################## -## CMakeLists.txt for the MPI test ## -############################################## - -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - +## mpitest add_executable(mpitest main.cc) target_link_libraries(mpitest astaroth_core astaroth_utils) diff --git a/samples/mpitest/main0.c b/samples/mpitest/main0.c deleted file mode 100644 index b5487a2..0000000 --- a/samples/mpitest/main0.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - Copyright (C) 2014-2020, Johannes Pekkila, Miikka Vaisala. - - This file is part of Astaroth. - - Astaroth is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Astaroth is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Astaroth. If not, see . -*/ -/** - Running: mpirun -np -*/ -#undef NDEBUG // Assert always -#include -#include -#include -#include - -#include "astaroth.h" - -#include - -// From Astaroth Utils -#include "src/utils/config_loader.h" -#include "src/utils/memory.h" - -static void -distribute_mesh(const AcMesh* src, AcMesh* dst) -{ - MPI_Datatype datatype = MPI_FLOAT; - if (sizeof(AcReal) == 8) - datatype = MPI_DOUBLE; - - int process_id, num_processes; - MPI_Comm_rank(MPI_COMM_WORLD, &process_id); - MPI_Comm_size(MPI_COMM_WORLD, &num_processes); - - const size_t count = acVertexBufferSize(dst->info); - for (int i = 0; i < NUM_VTXBUF_HANDLES; ++i) { - - // Communicate to self - if (process_id == 0) { - assert(src); - assert(dst); - memcpy(&dst->vertex_buffer[i][0], // - &src->vertex_buffer[i][0], // - count * sizeof(src->vertex_buffer[i][0])); - } - // Communicate to others - for (int j = 1; j < num_processes; ++j) { - if (process_id == 0) { - assert(src); - - // Send - // TODO RECHECK THESE j INDICES - const size_t src_idx = j * dst->info.int_params[AC_mx] * - dst->info.int_params[AC_my] * src->info.int_params[AC_nz] / - num_processes; - - MPI_Send(&src->vertex_buffer[i][src_idx], count, datatype, j, 0, MPI_COMM_WORLD); - } - else { - assert(dst); - - // Recv - const size_t dst_idx = 0; - MPI_Status status; - MPI_Recv(&dst->vertex_buffer[i][dst_idx], count, datatype, 0, 0, MPI_COMM_WORLD, - &status); - } - } - } -} - -static void -gather_mesh(const AcMesh* src, AcMesh* dst) -{ - MPI_Datatype datatype = MPI_FLOAT; - if (sizeof(AcReal) == 8) - datatype = MPI_DOUBLE; - - int process_id, num_processes; - MPI_Comm_rank(MPI_COMM_WORLD, &process_id); - MPI_Comm_size(MPI_COMM_WORLD, &num_processes); - - size_t count = acVertexBufferSize(src->info); - - for (int i = 0; i < NUM_VTXBUF_HANDLES; ++i) { - // Communicate to self - if (process_id == 0) { - assert(src); - assert(dst); - memcpy(&dst->vertex_buffer[i][0], // - &src->vertex_buffer[i][0], // - count * sizeof(AcReal)); - } - - // Communicate to others - for (int j = 1; j < num_processes; ++j) { - if (process_id == 0) { - // Recv - // const size_t dst_idx = j * acVertexBufferCompdomainSize(dst->info); - const size_t dst_idx = j * dst->info.int_params[AC_mx] * - dst->info.int_params[AC_my] * dst->info.int_params[AC_nz] / - num_processes; - - assert(dst_idx + count <= acVertexBufferSize(dst->info)); - MPI_Status status; - MPI_Recv(&dst->vertex_buffer[i][dst_idx], count, datatype, j, 0, MPI_COMM_WORLD, - &status); - } - else { - // Send - const size_t src_idx = 0; - - assert(src_idx + count <= acVertexBufferSize(src->info)); - MPI_Send(&src->vertex_buffer[i][src_idx], count, datatype, 0, 0, MPI_COMM_WORLD); - } - } - } -} - -int -main(void) -{ - MPI_Init(NULL, NULL); - - int num_processes, process_id; - MPI_Comm_size(MPI_COMM_WORLD, &num_processes); - MPI_Comm_rank(MPI_COMM_WORLD, &process_id); - - char processor_name[MPI_MAX_PROCESSOR_NAME]; - int name_len; - MPI_Get_processor_name(processor_name, &name_len); - printf("Processor %s. Process %d of %d.\n", processor_name, process_id, num_processes); - - AcMeshInfo mesh_info; - acLoadConfig(AC_DEFAULT_CONFIG, &mesh_info); - - AcMesh* main_mesh = NULL; - ModelMesh* model_mesh = NULL; - if (process_id == 0) { - main_mesh = acmesh_create(mesh_info); - acmesh_init_to(INIT_TYPE_RANDOM, main_mesh); - model_mesh = modelmesh_create(mesh_info); - acmesh_to_modelmesh(*main_mesh, model_mesh); - } - - AcMeshInfo submesh_info = mesh_info; - submesh_info.int_params[AC_nz] /= num_processes; - update_config(&submesh_info); - - AcMesh* submesh = acmesh_create(submesh_info); - - ///////////////////// - distribute_mesh(main_mesh, submesh); - gather_mesh(submesh, main_mesh); - ///////////////////////// - // Autotest - bool is_acceptable = verify_meshes(*model_mesh, *main_mesh); - ///// - - acmesh_destroy(submesh); - - if (process_id == 0) { - modelmesh_destroy(model_mesh); - acmesh_destroy(main_mesh); - } - - MPI_Finalize(); - return EXIT_SUCCESS; -} diff --git a/samples/mpitest/main1.c b/samples/mpitest/main1.c deleted file mode 100644 index 7322fcd..0000000 --- a/samples/mpitest/main1.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - Copyright (C) 2014-2020, Johannes Pekkila, Miikka Vaisala. - - This file is part of Astaroth. - - Astaroth is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Astaroth is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Astaroth. If not, see . -*/ -/** - Running: mpirun -np -*/ -#undef NDEBUG // Assert always -#include -#include -#include -#include - -#include "astaroth.h" - -#include - -// From Astaroth Utils -#include "src/utils/config_loader.h" -#include "src/utils/memory.h" -#include "src/utils/verification.h" - -static void -distribute_mesh(const AcMesh src, AcMesh* dst) -{ - MPI_Barrier(MPI_COMM_WORLD); - printf("Distributing mesh...\n"); - - MPI_Datatype datatype = MPI_FLOAT; - if (sizeof(AcReal) == 8) - datatype = MPI_DOUBLE; - - int pid, num_processes; - MPI_Comm_rank(MPI_COMM_WORLD, &pid); - MPI_Comm_size(MPI_COMM_WORLD, &num_processes); - - const size_t count = acVertexBufferSize(dst->info); - for (int i = 0; i < NUM_VTXBUF_HANDLES; ++i) { - - if (pid == 0) { - // Communicate to self - assert(dst); - memcpy(&dst->vertex_buffer[i][0], // - &src.vertex_buffer[i][0], // - count * sizeof(src.vertex_buffer[i][0])); - - // Communicate to others - for (int j = 1; j < num_processes; ++j) { - const size_t src_idx = acVertexBufferIdx( - 0, 0, j * src.info.int_params[AC_nz] / num_processes, src.info); - - MPI_Send(&src.vertex_buffer[i][src_idx], count, datatype, j, 0, MPI_COMM_WORLD); - } - } - else { - assert(dst); - - // Recv - const size_t dst_idx = 0; - MPI_Status status; - MPI_Recv(&dst->vertex_buffer[i][dst_idx], count, datatype, 0, 0, MPI_COMM_WORLD, - &status); - } - } -} - -static void -gather_mesh(const AcMesh src, AcMesh* dst) -{ - MPI_Barrier(MPI_COMM_WORLD); - printf("Gathering mesh...\n"); - MPI_Datatype datatype = MPI_FLOAT; - if (sizeof(AcReal) == 8) - datatype = MPI_DOUBLE; - - int pid, num_processes; - MPI_Comm_rank(MPI_COMM_WORLD, &pid); - MPI_Comm_size(MPI_COMM_WORLD, &num_processes); - - size_t count = acVertexBufferSize(src.info); - - for (int i = 0; i < NUM_VTXBUF_HANDLES; ++i) { - // Communicate to self - if (pid == 0) { - assert(dst); - memcpy(&dst->vertex_buffer[i][0], // - &src.vertex_buffer[i][0], // - count * sizeof(src.vertex_buffer[i][0])); - - for (int j = 1; j < num_processes; ++j) { - // Recv - const size_t dst_idx = acVertexBufferIdx( - 0, 0, j * dst->info.int_params[AC_nz] / num_processes, dst->info); - - assert(dst_idx + count <= acVertexBufferSize(dst->info)); - MPI_Status status; - MPI_Recv(&dst->vertex_buffer[i][dst_idx], count, datatype, j, 0, MPI_COMM_WORLD, - &status); - } - } - else { - // Send - const size_t src_idx = 0; - - assert(src_idx + count <= acVertexBufferSize(src.info)); - MPI_Send(&src.vertex_buffer[i][src_idx], count, datatype, 0, 0, MPI_COMM_WORLD); - } - } -} - -static void -communicate_halos(AcMesh* submesh) -{ - MPI_Barrier(MPI_COMM_WORLD); - printf("Communicating bounds...\n"); - MPI_Datatype datatype = MPI_FLOAT; - if (sizeof(AcReal) == 8) - datatype = MPI_DOUBLE; - - int pid, num_processes; - MPI_Comm_rank(MPI_COMM_WORLD, &pid); - MPI_Comm_size(MPI_COMM_WORLD, &num_processes); - - const size_t count = submesh->info.int_params[AC_mx] * submesh->info.int_params[AC_my] * NGHOST; - - for (int i = 0; i < NUM_VTXBUF_HANDLES; ++i) { - { // Front - // ...|ooooxxx|... -> xxx|ooooooo|... - const size_t src_idx = acVertexBufferIdx(0, 0, submesh->info.int_params[AC_nz], - submesh->info); - const size_t dst_idx = acVertexBufferIdx(0, 0, 0, submesh->info); - const int send_pid = (pid + 1) % num_processes; - const int recv_pid = (pid + num_processes - 1) % num_processes; - - MPI_Request request; - MPI_Isend(&submesh->vertex_buffer[i][src_idx], count, datatype, send_pid, i, - MPI_COMM_WORLD, &request); - fflush(stdout); - - MPI_Status status; - MPI_Recv(&submesh->vertex_buffer[i][dst_idx], count, datatype, recv_pid, i, - MPI_COMM_WORLD, &status); - - MPI_Wait(&request, &status); - } - { // Back - // ...|ooooooo|xxx <- ...|xxxoooo|... - const size_t src_idx = acVertexBufferIdx(0, 0, NGHOST, submesh->info); - const size_t dst_idx = acVertexBufferIdx(0, 0, NGHOST + submesh->info.int_params[AC_nz], - submesh->info); - const int send_pid = (pid + num_processes - 1) % num_processes; - const int recv_pid = (pid + 1) % num_processes; - - MPI_Request request; - MPI_Isend(&submesh->vertex_buffer[i][src_idx], count, datatype, send_pid, - NUM_VTXBUF_HANDLES + i, MPI_COMM_WORLD, &request); - - MPI_Status status; - MPI_Recv(&submesh->vertex_buffer[i][dst_idx], count, datatype, recv_pid, - NUM_VTXBUF_HANDLES + i, MPI_COMM_WORLD, &status); - - MPI_Wait(&request, &status); - } - } -} - -int -main(void) -{ - int num_processes, pid; - MPI_Init(NULL, NULL); - MPI_Comm_size(MPI_COMM_WORLD, &num_processes); - MPI_Comm_rank(MPI_COMM_WORLD, &pid); - - char processor_name[MPI_MAX_PROCESSOR_NAME]; - int name_len; - MPI_Get_processor_name(processor_name, &name_len); - printf("Processor %s. Process %d of %d.\n", processor_name, pid, num_processes); - - AcMeshInfo info; - acLoadConfig(AC_DEFAULT_CONFIG, &info); - - AcMesh model, candidate, submesh; - - // Master CPU - if (pid == 0) { - acMeshCreate(info, &model); - acMeshCreate(info, &candidate); - - acMeshRandomize(&model); - acMeshApplyPeriodicBounds(&model); - } - - assert(info.int_params[AC_nz] % num_processes == 0); - - AcMeshInfo submesh_info = info; - submesh_info.int_params[AC_nz] /= num_processes; - acUpdateConfig(&submesh_info); - acMeshCreate(submesh_info, &submesh); - - distribute_mesh(model, &submesh); - - // GPU-GPU communication - /* - const int device_id = pid % acGetNumDevicesPerNode(); - - Device device; - acDeviceCreate(device_id, submesh_info, &device); - - acDeviceLoadMesh(device, STREAM_DEFAULT, submesh); - acDeviceCommunicateHalosMPI(device); - acDeviceStoreMesh(device, STREAM_DEFAULT, &submesh); - - acDeviceDestroy(device); - */ - - // GPU-CPU-CPU-GPU communication - const int device_id = pid % acGetNumDevicesPerNode(); - - Device device; - acDeviceCreate(device_id, submesh_info, &device); - - acDeviceLoadMesh(device, STREAM_DEFAULT, submesh); - acDevicePeriodicBoundconds(device, STREAM_DEFAULT, (int3){0, 0, 0}, - (int3){submesh_info.int_params[AC_mx], - submesh_info.int_params[AC_my], - submesh_info.int_params[AC_mz]}); - acDeviceStoreMesh(device, STREAM_DEFAULT, &submesh); - communicate_halos(&submesh); - - acDeviceDestroy(device); - // - - // - // CPU-CPU communication - // communicate_halos(&submesh); - // - gather_mesh(submesh, &candidate); - - acMeshDestroy(&submesh); - // Master CPU - if (pid == 0) { - acVerifyMesh(model, candidate); - acMeshDestroy(&model); - acMeshDestroy(&candidate); - } - - // GPU - /* - Device device; - acDeviceCreate(pid, info, &device); - - acDeviceLoadMesh(device, STREAM_DEFAULT, model); - - acDeviceStoreMesh(device, STREAM_DEFAULT, &candidate); - acDeviceDestroy(device); - */ - // - - MPI_Finalize(); - return EXIT_SUCCESS; -}