diff --git a/include/picongpu/algorithms/AssignedTrilinearInterpolation.hpp b/include/picongpu/algorithms/AssignedTrilinearInterpolation.hpp index c805f2647e..9c644d1a5f 100644 --- a/include/picongpu/algorithms/AssignedTrilinearInterpolation.hpp +++ b/include/picongpu/algorithms/AssignedTrilinearInterpolation.hpp @@ -19,6 +19,7 @@ #pragma once +#include #include #include @@ -67,13 +68,17 @@ namespace picongpu { using type = typename ::pmacc::result_of::Functor::type; + constexpr auto iterations = T_end - T_begin + 1; auto result_z = type(0.0); + PMACC_UNROLL(iterations) for(int z = T_begin; z <= T_end; ++z) { auto result_y = type(0.0); + PMACC_UNROLL(iterations) for(int y = T_begin; y <= T_end; ++y) { auto result_x = type(0.0); + PMACC_UNROLL(iterations) for(int x = T_begin; x <= T_end; ++x) /* a form factor is the "amount of particle" that is affected by this cell * so we have to sum over: cell_value * form_factor diff --git a/include/picongpu/algorithms/FieldToParticleInterpolation.hpp b/include/picongpu/algorithms/FieldToParticleInterpolation.hpp index b29be938e4..79733b6892 100644 --- a/include/picongpu/algorithms/FieldToParticleInterpolation.hpp +++ b/include/picongpu/algorithms/FieldToParticleInterpolation.hpp @@ -24,6 +24,7 @@ #include "picongpu/algorithms/ShiftCoordinateSystem.hpp" +#include #include #include #include @@ -76,6 +77,7 @@ namespace picongpu using Supports = typename pmacc::math::CT::make_Int::type; typename Cursor::ValueType result; + PMACC_UNROLL(Cursor::ValueType::dim) for(uint32_t i = 0; i < Cursor::ValueType::dim; i++) { auto fieldComponent diff --git a/include/pmacc/attribute/unroll.hpp b/include/pmacc/attribute/unroll.hpp new file mode 100644 index 0000000000..113ef642ef --- /dev/null +++ b/include/pmacc/attribute/unroll.hpp @@ -0,0 +1,43 @@ +/* Copyright 2021 Bernhard Manfred Gruber + * + * This file is part of PMacc. + * + * PMacc is free software: you can redistribute it and/or modify + * it under the terms of either the GNU General Public License or + * the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PMacc 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser General Public License along with PMacc. + * If not, see . + */ + +#pragma once + +#ifndef PMACC_UNROLL +# define PMACC_PRAGMA(x) _Pragma(# x) + +# if defined(__clang__) || defined(__INTEL_LLVM_COMPILER) || defined(__NVCC__) +# define PMACC_UNROLL(var) PMACC_PRAGMA(unroll var) +# elif defined(__INTEL_COMPILER) // check Intel before g++, because Intel defines __GNUG__ +# define PMACC_UNROLL(var) PMACC_PRAGMA(unroll(var)) +# elif defined(__GNUG__) +// g++ does support an unroll pragma but it does not accept the value of a template argument (at least until g++-11.2) +// see also: https://stackoverflow.com/q/63404539/2406044 +// #define PMACC_UNROLL(var) PMACC_PRAGMA(GCC unroll var) +# define PMACC_UNROLL(var) +# elif defined(_MSC_VER) +// MSVC does not support a pragma for unrolling +# define PMACC_UNROLL(var) +# else +# define PMACC_UNROLL(var) +# warning PMACC_UNROLL is not implemented for your compiler +# endif +#endif