Merge branch 'master' into io_improvement_20190924

This commit is contained in:
Miikka Vaisala
2019-10-02 10:47:51 +08:00
32 changed files with 848 additions and 167 deletions

View File

@@ -11,6 +11,7 @@ set(CUDA_ARCH_FLAGS -gencode arch=compute_37,code=sm_37
-gencode arch=compute_50,code=sm_50
-gencode arch=compute_60,code=sm_60
-gencode arch=compute_61,code=sm_61
-gencode arch=compute_70,code=sm_70
-lineinfo
-ftz=true # Flush denormalized floats to zero
-std=c++11

View File

@@ -357,7 +357,7 @@ acDeviceAutoOptimize(const Device device)
cudaEventRecord(tstart); // ---------------------------------------- Timing start
acDeviceLoadScalarConstant(device, STREAM_DEFAULT, AC_dt, FLT_EPSILON);
acDeviceLoadScalarUniform(device, STREAM_DEFAULT, AC_dt, FLT_EPSILON);
for (int i = 0; i < num_iterations; ++i)
solve<2><<<bpg, tpb>>>(start, end, device->vba);
@@ -416,7 +416,7 @@ acDeviceSwapBuffers(const Device device)
}
AcResult
acDeviceLoadScalarConstant(const Device device, const Stream stream, const AcRealParam param,
acDeviceLoadScalarUniform(const Device device, const Stream stream, const AcRealParam param,
const AcReal value)
{
cudaSetDevice(device->id);
@@ -427,7 +427,7 @@ acDeviceLoadScalarConstant(const Device device, const Stream stream, const AcRea
}
AcResult
acDeviceLoadVectorConstant(const Device device, const Stream stream, const AcReal3Param param,
acDeviceLoadVectorUniform(const Device device, const Stream stream, const AcReal3Param param,
const AcReal3 value)
{
cudaSetDevice(device->id);
@@ -438,7 +438,7 @@ acDeviceLoadVectorConstant(const Device device, const Stream stream, const AcRea
}
AcResult
acDeviceLoadIntConstant(const Device device, const Stream stream, const AcIntParam param,
acDeviceLoadIntUniform(const Device device, const Stream stream, const AcIntParam param,
const int value)
{
cudaSetDevice(device->id);
@@ -449,7 +449,7 @@ acDeviceLoadIntConstant(const Device device, const Stream stream, const AcIntPar
}
AcResult
acDeviceLoadInt3Constant(const Device device, const Stream stream, const AcInt3Param param,
acDeviceLoadInt3Uniform(const Device device, const Stream stream, const AcInt3Param param,
const int3 value)
{
cudaSetDevice(device->id);
@@ -670,7 +670,7 @@ acDeviceIntegrateSubstep(const Device device, const Stream stream, const int ste
(unsigned int)ceil(n.y / AcReal(tpb.y)), //
(unsigned int)ceil(n.z / AcReal(tpb.z)));
acDeviceLoadScalarConstant(device, stream, AC_dt, dt);
acDeviceLoadScalarUniform(device, stream, AC_dt, dt);
if (step_number == 0)
solve<0><<<bpg, tpb, 0, device->streams[stream]>>>(start, end, device->vba);
else if (step_number == 1)

View File

@@ -1,2 +0,0 @@
# Ignore the generated headers
stencil_process.cuh stencil_assembly.cuh

View File

@@ -429,7 +429,7 @@ acNodeLoadConstant(const Node node, const Stream stream, const AcRealParam param
acNodeSynchronizeStream(node, stream);
// #pragma omp parallel for
for (int i = 0; i < node->num_devices; ++i) {
acDeviceLoadScalarConstant(node->devices[i], stream, param, value);
acDeviceLoadScalarUniform(node->devices[i], stream, param, value);
}
return AC_SUCCESS;
}

View File

@@ -0,0 +1,11 @@
## 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
add_executable(ac_simulate simulation.cc)
target_link_libraries(ac_simulate PRIVATE astaroth_core astaroth_utils)
add_definitions(-DAC_DEFAULT_CONFIG="${CMAKE_SOURCE_DIR}/config/astaroth.conf")

View File

@@ -0,0 +1,77 @@
/*
Copyright (C) 2014-2019, Johannes Pekkilae, Miikka Vaeisalae.
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 <http://www.gnu.org/licenses/>.
*/
#include "src/utils/config_loader.h"
#include "src/utils/memory.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
int
run_simulation(const char* config_path)
{
AcMeshInfo info;
acLoadConfig(config_path, &info);
AcMesh mesh;
acMeshCreate(info, &mesh);
acMeshClear(&mesh);
acInit(info);
acLoad(mesh);
const size_t num_steps = 10;
for (size_t i = 0; i < num_steps; ++i) {
const AcReal dt = 1; // JP: TODO! Set timestep here!
// JP: TODO! Make sure that AcMeshInfo parameters are properly initialized before calling
// acIntegrate()
// NANs indicate that either dt is too large or something was uninitalized
acIntegrate(dt);
}
for (int i = 0; i < NUM_VTXBUF_HANDLES; ++i) {
printf("%s:\n", vtxbuf_names[i]);
printf("\tmax: %g\n", (double)acReduceScal(RTYPE_MAX, VertexBufferHandle(i)));
printf("\tmin: %g\n", (double)acReduceScal(RTYPE_MIN, VertexBufferHandle(i)));
printf("\trms: %g\n", (double)acReduceScal(RTYPE_RMS, VertexBufferHandle(i)));
printf("\texp rms: %g\n", (double)acReduceScal(RTYPE_RMS_EXP, VertexBufferHandle(i)));
}
acStore(&mesh);
acQuit();
acMeshDestroy(&mesh);
return EXIT_SUCCESS;
}
int
main(int argc, char* argv[])
{
printf("Args: \n");
for (int i = 0; i < argc; ++i)
printf("%d: %s\n", i, argv[i]);
char* config_path;
(argc == 3) ? config_path = strdup(argv[2]) : config_path = strdup(AC_DEFAULT_CONFIG);
printf("Config path: %s\n", config_path);
assert(config_path);
run_simulation(config_path);
free(config_path);
return EXIT_SUCCESS;
}

10
src/utils/CMakeLists.txt Normal file
View File

@@ -0,0 +1,10 @@
## C++ standard
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
## Compilation flags
add_compile_options(-Wall -Wextra -Werror -Wdouble-promotion -Wfloat-conversion -Wshadow)
## Compile
add_library(astaroth_utils STATIC config_loader.c memory.c)
target_link_libraries(astaroth_utils PRIVATE astaroth_core)

143
src/utils/config_loader.c Normal file
View File

@@ -0,0 +1,143 @@
/*
Copyright (C) 2014-2019, Johannes Pekkilae, Miikka Vaeisalae.
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 <http://www.gnu.org/licenses/>.
*/
/**
* @file
* \brief Brief info.
*
* Detailed info.
*
*/
#include "config_loader.h"
#include <assert.h>
#include <limits.h> // UINT_MAX
#include <math.h>
#include <stdint.h> // uint8_t, uint32_t
#include <stdio.h> // print
#include <string.h> // memset
//#include "src/core/math_utils.h"
/**
\brief Find the index of the keyword in names
\return Index in range 0...n if the keyword is in names. -1 if the keyword was
not found.
*/
static int
find_str(const char keyword[], const char* names[], const int n)
{
for (int i = 0; i < n; ++i)
if (!strcmp(keyword, names[i]))
return i;
return -1;
}
static void
parse_config(const char* path, AcMeshInfo* config)
{
FILE* fp;
fp = fopen(path, "r");
// For knowing which .conf file will be used
printf("Config file path: \n %s \n ", path);
assert(fp != NULL);
const size_t BUF_SIZE = 128;
char keyword[BUF_SIZE];
char value[BUF_SIZE];
int items_matched;
while ((items_matched = fscanf(fp, "%s = %s", keyword, value)) != EOF) {
if (items_matched < 2)
continue;
int idx = -1;
if ((idx = find_str(keyword, intparam_names, NUM_INT_PARAMS)) >= 0)
config->int_params[idx] = atoi(value);
else if ((idx = find_str(keyword, realparam_names, NUM_REAL_PARAMS)) >= 0)
config->real_params[idx] = (AcReal)(atof(value));
}
fclose(fp);
}
void
update_config(AcMeshInfo* config)
{
config->int_params[AC_mx] = config->int_params[AC_nx] + STENCIL_ORDER;
///////////// PAD TEST
// config->int_params[AC_mx] = config->int_params[AC_nx] + STENCIL_ORDER + PAD_SIZE;
///////////// PAD TEST
config->int_params[AC_my] = config->int_params[AC_ny] + STENCIL_ORDER;
config->int_params[AC_mz] = config->int_params[AC_nz] + STENCIL_ORDER;
// Bounds for the computational domain, i.e. nx_min <= i < nx_max
config->int_params[AC_nx_min] = STENCIL_ORDER / 2;
config->int_params[AC_nx_max] = config->int_params[AC_nx_min] + config->int_params[AC_nx];
config->int_params[AC_ny_min] = STENCIL_ORDER / 2;
config->int_params[AC_ny_max] = config->int_params[AC_ny] + STENCIL_ORDER / 2;
config->int_params[AC_nz_min] = STENCIL_ORDER / 2;
config->int_params[AC_nz_max] = config->int_params[AC_nz] + STENCIL_ORDER / 2;
// Spacing
config->real_params[AC_inv_dsx] = (AcReal)(1.) / config->real_params[AC_dsx];
config->real_params[AC_inv_dsy] = (AcReal)(1.) / config->real_params[AC_dsy];
config->real_params[AC_inv_dsz] = (AcReal)(1.) / config->real_params[AC_dsz];
/* Additional helper params */
// Int helpers
config->int_params[AC_mxy] = config->int_params[AC_mx] * config->int_params[AC_my];
config->int_params[AC_nxy] = config->int_params[AC_nx] * config->int_params[AC_ny];
config->int_params[AC_nxyz] = config->int_params[AC_nxy] * config->int_params[AC_nz];
}
/**
\brief Loads data from astaroth.conf into a config struct.
\return AC_SUCCESS on success, AC_FAILURE if there are potentially uninitialized values.
*/
AcResult
acLoadConfig(const char* config_path, AcMeshInfo* config)
{
int retval = AC_SUCCESS;
assert(config_path);
// memset reads the second parameter as a byte even though it says int in
// the function declaration
memset(config, (uint8_t)0xFF, sizeof(*config));
parse_config(config_path, config);
update_config(config);
#if VERBOSE_PRINTING // Defined in astaroth.h
printf("###############################################################\n");
printf("Config dimensions recalculated:\n");
acPrintMeshInfo(*config);
printf("###############################################################\n");
#endif
// sizeof(config) must be a multiple of 4 bytes for this to work
assert(sizeof(*config) % sizeof(uint32_t) == 0);
for (size_t i = 0; i < sizeof(*config) / sizeof(uint32_t); ++i) {
if (((uint32_t*)config)[i] == (uint32_t)0xFFFFFFFF) {
fprintf(stderr, "Some config values may be uninitialized. "
"See that all are defined in astaroth.conf\n");
retval = AC_FAILURE;
}
}
return retval;
}

37
src/utils/config_loader.h Normal file
View File

@@ -0,0 +1,37 @@
/*
Copyright (C) 2014-2019, Johannes Pekkilae, Miikka Vaeisalae.
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 <http://www.gnu.org/licenses/>.
*/
/**
* @file
* \brief Functions for loading and updating AcMeshInfo.
*
*/
#pragma once
#include "astaroth.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Loads data from the config file */
AcResult acLoadConfig(const char* config_path, AcMeshInfo* config);
#ifdef __cplusplus
} // extern "C"
#endif

64
src/utils/memory.c Normal file
View File

@@ -0,0 +1,64 @@
/*
Copyright (C) 2014-2019, Johannes Pekkilae, Miikka Vaeisalae.
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 <http://www.gnu.org/licenses/>.
*/
#include "memory.h"
#include <math.h>
#include <string.h>
#include "src/core/errchk.h"
AcResult
acMeshCreate(const AcMeshInfo info, AcMesh* mesh)
{
mesh->info = info;
const size_t bytes = acVertexBufferSizeBytes(mesh->info);
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w) {
mesh->vertex_buffer[w] = malloc(bytes);
ERRCHK_ALWAYS(mesh->vertex_buffer[w]);
}
return AC_SUCCESS;
}
AcResult
acMeshDestroy(AcMesh* mesh)
{
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
free(mesh->vertex_buffer[w]);
return AC_SUCCESS;
}
AcResult
acMeshSet(const AcReal value, AcMesh* mesh)
{
const int n = acVertexBufferSize(mesh->info);
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
for (int i = 0; i < n; ++i)
mesh->vertex_buffer[w][i] = value;
return AC_SUCCESS;
}
AcResult
acMeshClear(AcMesh* mesh)
{
return acMeshSet(0, mesh);
}

44
src/utils/memory.h Normal file
View File

@@ -0,0 +1,44 @@
/*
Copyright (C) 2014-2019, Johannes Pekkilae, Miikka Vaeisalae.
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 <http://www.gnu.org/licenses/>.
*/
/**
* @file
* \brief Brief info.
*
* Detailed info.
*
*/
#pragma once
#include "astaroth.h"
#ifdef __cplusplus
extern "C" {
#endif
AcResult acMeshCreate(const AcMeshInfo mesh_info, AcMesh* mesh);
AcResult acMeshDestroy(AcMesh* mesh);
AcResult acMeshSet(const AcReal value, AcMesh* mesh);
AcResult acMeshClear(AcMesh* mesh);
#ifdef __cplusplus
} // extern "C"
#endif