Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 40 additions & 28 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ option(MeshFields_USE_Cabana "Build with the Cabana storage backend" OFF)

find_package(Kokkos REQUIRED)
find_package(Omega_h REQUIRED)
#Clear the omegah compilation flags that it passes to cuda. Using the
# kokkos target, and nvcc_wrapper, provide sufficient flags.
set_property(TARGET Omega_h::omega_h PROPERTY INTERFACE_COMPILE_OPTIONS "")

if(MeshFields_USE_Cabana)
find_package(Cabana 0.7.0 REQUIRED)
Expand Down Expand Up @@ -112,8 +109,8 @@ endif()
enable_testing()
include(CTest)

option(IS_TESTING "Build for CTest" OFF)
message(STATUS "IS_TESTING: ${IS_TESTING}")
option(MeshFields_IS_TESTING "Build for CTest" OFF)
message(STATUS "MeshFields_IS_TESTING: ${MeshFields_IS_TESTING}")

#check for valgrind
find_program(VALGRIND_CMD valgrind DOC "Location of the valgrind program")
Expand All @@ -124,72 +121,87 @@ function(test_func_impl TEST_NAME)
# need to run as a cmake script to capture assert and other 'system failures'
# https://cmake.org/cmake/help/latest/prop_test/WILL_FAIL.html#prop_test:WILL_FAIL
add_test(NAME ${TEST_NAME} COMMAND ${CMAKE_COMMAND} -E env ${TEST_STR})
if(TEST ${TEST_NAME})
set_property(TEST ${TEST_NAME} PROPERTY LABELS "meshfields::base")
endif()
endfunction(test_func_impl)

function(test_func TEST_NAME)
#smoke tests that are always enabled
function(smoke_test_func TEST_NAME)
test_func_impl(${TEST_NAME} ${ARGN})
if(TEST ${TEST_NAME})
set_property(TEST ${TEST_NAME} PROPERTY LABELS "base")
set_property(TEST ${TEST_NAME} PROPERTY LABELS "meshfields::smoke")
endif()
endfunction(smoke_test_func)

function(test_func TEST_NAME)
if(MeshFields_IS_TESTING)
test_func_impl(${TEST_NAME} ${ARGN})
endif()
endfunction(test_func)

# Unlike test_func, will_fail_test_func assumes the command for the test will fail
function(will_fail_test_func TEST_NAME)
test_func_impl(${TEST_NAME} ${ARGN})
set_property(TEST ${TEST_NAME} PROPERTY WILL_FAIL TRUE)
if(TEST ${TEST_NAME})
set_property(TEST ${TEST_NAME} PROPERTY LABELS "base")
if(MeshFields_IS_TESTING)
test_func_impl(${TEST_NAME} ${ARGN})
set_property(TEST ${TEST_NAME} PROPERTY WILL_FAIL TRUE)
endif()
endfunction()

function(will_fail_valgrind_test_func TEST_NAME)
if(VALGRIND_CMD)
test_func_impl(${TEST_NAME} ${VALGRIND_CMD} ${ARGN})
set_property(TEST ${TEST_NAME} PROPERTY
FAIL_REGULAR_EXPRESSION "Invalid read;Invalid write"
)
set_property(TEST ${TEST_NAME} PROPERTY WILL_FAIL TRUE)
if(TEST ${TEST_NAME})
set_property(TEST ${TEST_NAME} PROPERTY LABELS "base")
if(MeshFields_IS_TESTING)
if(VALGRIND_CMD)
test_func_impl(${TEST_NAME} ${VALGRIND_CMD} ${ARGN})
set_property(TEST ${TEST_NAME} PROPERTY
FAIL_REGULAR_EXPRESSION "Invalid read;Invalid write"
)
set_property(TEST ${TEST_NAME} PROPERTY WILL_FAIL TRUE)
endif()
endif()
endfunction()

function(meshfields_add_exe EXE_NAME EXE_SRC)
#smoke executables are always built
function(meshfields_add_smoke_exe EXE_NAME EXE_SRC)
add_executable(${EXE_NAME} ${EXE_SRC})
target_link_libraries(${EXE_NAME} PRIVATE meshfields)
endfunction()

# Creating minimal reproduction of error
meshfields_add_exe(KokkosTests test/testKokkos.cpp)
function(meshfields_add_exe EXE_NAME EXE_SRC)
if(MeshFields_IS_TESTING)
add_executable(${EXE_NAME} ${EXE_SRC})
target_link_libraries(${EXE_NAME} PRIVATE meshfields)
endif()
endfunction()

meshfields_add_smoke_exe(KokkosTests test/testKokkos.cpp)
meshfields_add_exe(SerializationTests test/testSerialize.cpp)
meshfields_add_exe(ElementTests test/testElement.cpp)
meshfields_add_exe(ElementJacobian1d test/testElementJacobian1d.cpp)
meshfields_add_exe(ElementJacobian2d test/testElementJacobian2d.cpp)
meshfields_add_exe(ElementJacobian3d test/testElementJacobian3d.cpp)
meshfields_add_exe(CountIntegrator test/testCountIntegrator.cpp)
meshfields_add_exe(OmegahTriTests test/testOmegahTri.cpp)
meshfields_add_smoke_exe(OmegahTriTests test/testOmegahTri.cpp)
meshfields_add_exe(ExceptionTest test/testExceptions.cpp)
meshfields_add_exe(PointMapping test/testPointMapping.cpp)
meshfields_add_exe(OmegahTetTest test/testOmegahTet.cpp)

if(MeshFields_USE_Cabana)
meshfields_add_exe(ControllerPerformance test/testControllerPerformance.cpp)
meshfields_add_exe(CabanaTests test/testCabana.cpp)
test_func(CabanaTests ./CabanaTests)
meshfields_add_smoke_exe(CabanaTests test/testCabana.cpp)
smoke_test_func(CabanaTests ./CabanaTests)
test_func(ControllerPerformance ./ControllerPerformance)
endif()

test_func(KokkosTests ./KokkosTests)
smoke_test_func(KokkosTests ./KokkosTests)
test_func(SerializationTests ./SerializationTests)
test_func(ElementTests ./ElementTests)
test_func(ElementJacobian1d ./ElementJacobian1d)
test_func(ElementJacobian2d ./ElementJacobian2d)
test_func(ElementJacobian3d ./ElementJacobian3d)
test_func(CountIntegrator ./CountIntegrator)
test_func(OmegahTriTests ./OmegahTriTests)
smoke_test_func(OmegahTriTests ./OmegahTriTests)
test_func(PointMapping ./PointMapping)
test_func(OmegahTetTest, ./OmegahTetTest)
test_func(OmegahTetTest ./OmegahTetTest)
if(MeshFields_USE_EXCEPTIONS)
# exception caught - no error
test_func(ExceptionTest ./ExceptionTest)
Expand Down
28 changes: 15 additions & 13 deletions src/MeshField_Element.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,14 +170,15 @@ struct FieldElement {
*/
KOKKOS_INLINE_FUNCTION ValArray
getValue(int ent, Kokkos::Array<Real, MeshEntDim + 1> localCoord) const {
assert(ent < numMeshEnts);
assert(ent >= 0);
assert(static_cast<size_t>(ent) < numMeshEnts);
ValArray c;
const auto shapeValues = shapeFn.getValues(localCoord);
for (int ci = 0; ci < NumComponents; ++ci)
for (size_t ci = 0; ci < NumComponents; ++ci)
c[ci] = 0;
for (auto topo : elm2dof.getTopology()) { // element topology
for (int ni = 0; ni < shapeFn.numNodes; ++ni) {
for (int ci = 0; ci < NumComponents; ++ci) {
for (size_t ni = 0; ni < shapeFn.numNodes; ++ni) {
for (size_t ci = 0; ci < NumComponents; ++ci) {
auto map = elm2dof(ni, ci, ent, topo);
const auto fval =
field(map.entity, map.node, map.component, map.topo);
Expand All @@ -194,8 +195,8 @@ struct FieldElement {
KOKKOS_INLINE_FUNCTION NodeArray getNodeValues(int ent) const {
NodeArray c;
for (auto topo : elm2dof.getTopology()) { // element topology
for (int ni = 0; ni < ShapeType::numNodes; ++ni) {
for (int d = 0; d < ShapeType::meshEntDim; ++d) {
for (size_t ni = 0; ni < ShapeType::numNodes; ++ni) {
for (size_t d = 0; d < ShapeType::meshEntDim; ++d) {
auto map = elm2dof(ni, d, ent, topo);
const auto fval =
field(map.entity, map.node, map.component, map.topo);
Expand All @@ -219,11 +220,12 @@ struct FieldElement {
* @return the result of evaluation
*/
KOKKOS_INLINE_FUNCTION Real getJacobian1d(int ent) const {
assert(ent < numMeshEnts);
assert(ent >= 0);
assert(static_cast<size_t>(ent) < numMeshEnts);
const auto nodalGradients = shapeFn.getLocalGradients();
const auto nodeValues = getNodeValues(ent);
auto g = nodalGradients[0] * nodeValues[0];
for (int i = 1; i < shapeFn.numNodes; ++i) {
for (size_t i = 1; i < shapeFn.numNodes; ++i) {
g = g + nodalGradients[i] * nodeValues[i];
}
return g;
Expand Down Expand Up @@ -328,7 +330,7 @@ struct FieldElement {
KOKKOS_LAMBDA(const int &ent, LO &lerrors) {
Real sum = 0;
LO isError = 0;
for (int i = 0; i < localCoords.extent(1); i++) {
for (size_t i = 0; i < localCoords.extent(1); i++) {
if (localCoords(ent, i) < 0)
isError++;
sum += localCoords(ent, i);
Expand Down Expand Up @@ -449,7 +451,7 @@ evaluate(FieldElement &fes, Kokkos::View<Real **> localCoords,
KOKKOS_LAMBDA(const int &ent, LO &lerrors) {
Real sum = 0;
LO isError = 0;
for (int i = 0; i < localCoords.extent(1); i++) {
for (size_t i = 0; i < localCoords.extent(1); i++) {
if (localCoords(ent, i) < 0)
isError++;
sum += localCoords(ent, i);
Expand Down Expand Up @@ -477,7 +479,7 @@ evaluate(FieldElement &fes, Kokkos::View<Real **> localCoords,
LO numLocalCoords;
Kokkos::deep_copy(numLocalCoords,
Kokkos::subview(offsets, offsets.size() - 1));
if (localCoords.extent(0) != numLocalCoords) {
if (localCoords.extent(0) != static_cast<size_t>(numLocalCoords)) {
fail("The size of dimension 0 of the local coordinates input array (%zu) "
"does not match the last entry of the offsets array (%d).\n",
localCoords.extent(0), numLocalCoords);
Expand All @@ -491,10 +493,10 @@ evaluate(FieldElement &fes, Kokkos::View<Real **> localCoords,
Kokkos::Array<Real, FieldElement::MeshEntDim + 1> lc;
// TODO use nested parallel for?
for (auto pt = offsets(ent); pt < offsets(ent + 1); pt++) {
for (int i = 0; i < localCoords.extent(1); i++) // better way?
for (size_t i = 0; i < localCoords.extent(1); i++) // better way?
lc[i] = localCoords(pt, i);
const auto val = fes.getValue(ent, lc);
for (int i = 0; i < numComponents; i++)
for (size_t i = 0; i < numComponents; i++)
res(pt, i) = val[i];
}
});
Expand Down
2 changes: 1 addition & 1 deletion src/MeshField_Field.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ template <class Slice> class Field {
* @return the size/extent
*/
KOKKOS_INLINE_FUNCTION
auto size(int i) const { return slice.size(i); }
size_t size(int i) const { return slice.size(i); }

/**
* access the underlying field at the specified index
Expand Down
1 change: 0 additions & 1 deletion src/MeshField_Integrate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ Kokkos::View<Real *> getIntegrationPointWeights(
std::vector<IntegrationPoint<FieldElement::MeshEntDim + 1>> ip) {
const auto numPtsPerElm = ip.size();
const auto numMeshEnts = fes.numMeshEnts;
const auto meshEntDim = fes.MeshEntDim;
Kokkos::View<Real *> weights("weights", numMeshEnts * numPtsPerElm);
// broadcast the points into the view - FIXME this is an inefficient use of
// memory
Expand Down
4 changes: 2 additions & 2 deletions src/MeshField_Shape.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace {
template <typename Array> KOKKOS_INLINE_FUNCTION bool sumsToOne(Array &xi) {
auto sum = 0.0;
for (int i = 0; i < xi.size(); i++) {
for (size_t i = 0; i < xi.size(); i++) {
sum += xi[i];
}
return (Kokkos::fabs(sum - 1) <= MeshField::MachinePrecision);
Expand All @@ -17,7 +17,7 @@ template <typename Array> KOKKOS_INLINE_FUNCTION bool sumsToOne(Array &xi) {
template <typename Array>
KOKKOS_INLINE_FUNCTION bool greaterThanOrEqualZero(Array &xi) {
auto gt = true;
for (int i = 0; i < xi.size(); i++) {
for (size_t i = 0; i < xi.size(); i++) {
gt = gt && (xi[i] >= 0);
}
return gt;
Expand Down
2 changes: 1 addition & 1 deletion test/testCountIntegrator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ void doRun(Omega_h::Mesh &mesh,

CountIntegrator countInt(fes);
countInt.process(fes);
assert(mesh.nelems() == countInt.getCount());
assert(static_cast<size_t>(mesh.nelems()) == countInt.getCount());
}

int main(int argc, char **argv) {
Expand Down
2 changes: 1 addition & 1 deletion test/testKokkos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ void kokkosControllerSizeTest() {
void kokkosFieldSizeTest() {
printf("== START kokkosFieldSizeTest ==\n");
const int a = 5, b = 4, c = 3, d = 2, e = 1;
const int psi[5] = {a, b, c, d, e};
const size_t psi[5] = {a, b, c, d, e};
{
using simple_static =
MeshField::KokkosController<MemorySpace, ExecutionSpace, int[a],
Expand Down
8 changes: 4 additions & 4 deletions test/testOmegahTet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ bool checkResult(Omega_h::Mesh &mesh, Result &result, CoordField coordField,
const auto y = globalCoords(pt, 1);
const auto z = globalCoords(pt, 2);
const auto expected = func(x, y, z);
for (int i = 0; i < numComp; ++i) {
for (size_t i = 0; i < numComp; ++i) {
const auto computed = result(pt, i);
MeshField::LO isError = 0;
if (Kokkos::fabs(computed - expected) >
Expand Down Expand Up @@ -96,7 +96,7 @@ void setVertices(Omega_h::Mesh &mesh, AnalyticFunction func, ShapeField field) {
const auto x = coords[vtx * MeshDim];
const auto y = coords[vtx * MeshDim + 1];
const auto z = coords[vtx * MeshDim + 2];
for (int i = 0; i < field.numComp; ++i) {
for (size_t i = 0; i < field.numComp; ++i) {
field(vtx, 0, i, MeshField::Vertex) = func(x, y, z);
}
};
Expand All @@ -121,7 +121,7 @@ void setEdges(Omega_h::Mesh &mesh, AnalyticFunction func, ShapeField field) {
(coords[left * MeshDim + 1] + coords[right * MeshDim + 1]) / 2.0;
const auto z =
(coords[left * MeshDim + 2] + coords[right * MeshDim + 2]) / 2.0;
for (int i = 0; i < field.numComp; ++i) {
for (size_t i = 0; i < field.numComp; ++i) {
field(edge, 0, i, MeshField::Edge) = func(x, y, z);
}
};
Expand All @@ -137,7 +137,7 @@ createElmAreaCoords(size_t numElements,
numElements * NumPtsPerElem);
Kokkos::parallel_for(
"setLocalCoords", numElements, KOKKOS_LAMBDA(const int &elm) {
for (int pt = 0; pt < NumPtsPerElem; pt++) {
for (size_t pt = 0; pt < NumPtsPerElem; pt++) {
lc(elm * NumPtsPerElem + pt, 0) = coords[pt * 4 + 0];
lc(elm * NumPtsPerElem + pt, 1) = coords[pt * 4 + 1];
lc(elm * NumPtsPerElem + pt, 2) = coords[pt * 4 + 2];
Expand Down
8 changes: 4 additions & 4 deletions test/testOmegahTri.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ bool checkResult(Omega_h::Mesh &mesh, Result &result, CoordField coordField,
const auto x = globalCoords(pt, 0);
const auto y = globalCoords(pt, 1);
const auto expected = func(x, y);
for (int i = 0; i < numComp; ++i) {
for (size_t i = 0; i < numComp; ++i) {
const auto computed = result(pt, i);
MeshField::LO isError = 0;
if (Kokkos::fabs(computed - expected) >
Expand Down Expand Up @@ -92,7 +92,7 @@ void setVertices(Omega_h::Mesh &mesh, AnalyticFunction func, ShapeField field) {
// - TODO should be encoded in the field?
const auto x = coords[vtx * MeshDim];
const auto y = coords[vtx * MeshDim + 1];
for (int i = 0; i < field.numComp; ++i) {
for (size_t i = 0; i < field.numComp; ++i) {
field(vtx, 0, i, MeshField::Vertex) = func(x, y);
}
};
Expand All @@ -115,7 +115,7 @@ void setEdges(Omega_h::Mesh &mesh, AnalyticFunction func, ShapeField field) {
const auto x = (coords[left * MeshDim] + coords[right * MeshDim]) / 2.0;
const auto y =
(coords[left * MeshDim + 1] + coords[right * MeshDim + 1]) / 2.0;
for (int i = 0; i < field.numComp; ++i) {
for (size_t i = 0; i < field.numComp; ++i) {
field(edge, 0, i, MeshField::Edge) = func(x, y);
}
};
Expand All @@ -131,7 +131,7 @@ createElmAreaCoords(size_t numElements,
numElements * NumPtsPerElem);
Kokkos::parallel_for(
"setLocalCoords", numElements, KOKKOS_LAMBDA(const int &elm) {
for (int pt = 0; pt < NumPtsPerElem; pt++) {
for (size_t pt = 0; pt < NumPtsPerElem; pt++) {
lc(elm * NumPtsPerElem + pt, 0) = coords[pt * 3 + 0];
lc(elm * NumPtsPerElem + pt, 1) = coords[pt * 3 + 1];
lc(elm * NumPtsPerElem + pt, 2) = coords[pt * 3 + 2];
Expand Down
Loading