diff --git a/include/picongpu/initialization/ParserGridDistribution.cpp b/include/picongpu/initialization/ParserGridDistribution.cpp new file mode 100644 index 00000000000..5d59dabb978 --- /dev/null +++ b/include/picongpu/initialization/ParserGridDistribution.cpp @@ -0,0 +1,142 @@ +/* Copyright 2013-2019 Axel Huebl, Rene Widera, Benjamin Worpitz + * + * This file is part of PIConGPU. + * + * PIConGPU 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. + * + * PIConGPU 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 PIConGPU. + * If not, see . + */ + +#include "picongpu/initialization/ParserGridDistribution.hpp" + +#include +#include +#include // std::vector +#include // std::string +#include // std::distance + +#include +#include + + +namespace picongpu +{ + + ParserGridDistribution::ParserGridDistribution( std::string const s ) + { + parsedInput = parse( s ); + } + + uint32_t + ParserGridDistribution::getOffset( uint32_t const devicePos, uint32_t const maxCells ) const + { + value_type::const_iterator iter = parsedInput.begin(); + // go to last device of these n subdomains extent{n} + uint32_t i = iter->count - 1u; + uint32_t sum = 0u; + + while( i < devicePos ) + { + // add last subdomain + sum += iter->extent * iter->count; + + ++iter; + // go to last device of these n subdomains extent{n} + i += iter->count; + } + + // add part of this subdomain that is before me + sum += iter->extent * ( devicePos + iter->count - i - 1u ); + + // check total number of cells + uint32_t sumTotal = 0u; + for( iter = parsedInput.begin(); iter != parsedInput.end(); ++iter ) + sumTotal += iter->extent * iter->count; + + PMACC_VERIFY( sumTotal == maxCells ); + + return sum; + } + + uint32_t + ParserGridDistribution::getLocalSize( uint32_t const devicePos ) const + { + value_type::const_iterator iter = parsedInput.begin(); + // go to last device of these n subdomains extent{n} + uint32_t i = iter->count - 1u; + + while( i < devicePos ) + { + ++iter; + // go to last device of these n subdomains extent{n} + i += iter->count; + } + + return iter->extent; + } + + void + ParserGridDistribution::verifyDevices( uint32_t const numDevices ) const + { + uint32_t numSubdomains = 0u; + for( SubdomainPair const & p : parsedInput ) + numSubdomains += p.count; + + PMACC_VERIFY( numSubdomains == numDevices ); + } + + ParserGridDistribution::value_type + ParserGridDistribution::parse( std::string const s ) const + { + boost::regex regFind( "[0-9]+(\\{[0-9]+\\})*", + boost::regex_constants::perl ); + + boost::sregex_token_iterator iter( s.begin( ), s.end( ), + regFind, 0 ); + boost::sregex_token_iterator end; + + value_type newInput; + newInput.reserve( std::distance( iter, end ) ); + + for(; iter != end; ++iter ) + { + std::string pM = *iter; + + // find count n and extent b of b{n} + boost::regex regCount( + "(.*\\{)|(\\})", + boost::regex_constants::perl + ); + std::string count = boost::regex_replace( pM, regCount, "" ); + + boost::regex regExtent( + "\\{.*\\}", + boost::regex_constants::perl + ); + std::string extent = boost::regex_replace( pM, regExtent, "" ); + + // no count {n} given (implies one) + if( count == *iter ) + count = "1"; + + const SubdomainPair g = { + boost::lexical_cast< uint32_t > ( extent ), + boost::lexical_cast< uint32_t > ( count ) + }; + newInput.emplace_back( g ); + } + + return newInput; + } + +} // namespace picongpu diff --git a/include/picongpu/initialization/ParserGridDistribution.hpp b/include/picongpu/initialization/ParserGridDistribution.hpp index 4f884590adf..dc5af8aa95e 100644 --- a/include/picongpu/initialization/ParserGridDistribution.hpp +++ b/include/picongpu/initialization/ParserGridDistribution.hpp @@ -19,13 +19,9 @@ #pragma once -#include #include // std::vector #include // std::string -#include // std::distance - -#include -#include +#include namespace picongpu @@ -52,41 +48,10 @@ class ParserGridDistribution using value_type = std::vector< SubdomainPair >; public: - ParserGridDistribution( std::string const s ) - { - parsedInput = parse( s ); - } + ParserGridDistribution( std::string const s ); uint32_t - getOffset( uint32_t const devicePos, uint32_t const maxCells ) const - { - value_type::const_iterator iter = parsedInput.begin(); - // go to last device of these n subdomains extent{n} - uint32_t i = iter->count - 1u; - uint32_t sum = 0u; - - while( i < devicePos ) - { - // add last subdomain - sum += iter->extent * iter->count; - - ++iter; - // go to last device of these n subdomains extent{n} - i += iter->count; - } - - // add part of this subdomain that is before me - sum += iter->extent * ( devicePos + iter->count - i - 1u ); - - // check total number of cells - uint32_t sumTotal = 0u; - for( iter = parsedInput.begin(); iter != parsedInput.end(); ++iter ) - sumTotal += iter->extent * iter->count; - - PMACC_VERIFY( sumTotal == maxCells ); - - return sum; - } + getOffset( uint32_t const devicePos, uint32_t const maxCells ) const; /** Get local Size of this dimension * @@ -94,21 +59,7 @@ class ParserGridDistribution * \return uint32_t with local number of cells */ uint32_t - getLocalSize( uint32_t const devicePos ) const - { - value_type::const_iterator iter = parsedInput.begin(); - // go to last device of these n subdomains extent{n} - uint32_t i = iter->count - 1u; - - while( i < devicePos ) - { - ++iter; - // go to last device of these n subdomains extent{n} - i += iter->count; - } - - return iter->extent; - } + getLocalSize( uint32_t const devicePos ) const; /** Verify the number of subdomains matches the devices * @@ -118,14 +69,7 @@ class ParserGridDistribution * \param[in] numDevices number of devices for this dimension */ void - verifyDevices( uint32_t const numDevices ) const - { - uint32_t numSubdomains = 0u; - for( SubdomainPair const & p : parsedInput ) - numSubdomains += p.count; - - PMACC_VERIFY( numSubdomains == numDevices ); - } + verifyDevices( uint32_t const numDevices ) const; private: value_type parsedInput; @@ -140,48 +84,7 @@ class ParserGridDistribution * \return std::vector with 2x uint32_t (extent, count) */ value_type - parse( std::string const s ) const - { - boost::regex regFind( "[0-9]+(\\{[0-9]+\\})*", - boost::regex_constants::perl ); - - boost::sregex_token_iterator iter( s.begin( ), s.end( ), - regFind, 0 ); - boost::sregex_token_iterator end; - - value_type newInput; - newInput.reserve( std::distance( iter, end ) ); - - for(; iter != end; ++iter ) - { - std::string pM = *iter; - - // find count n and extent b of b{n} - boost::regex regCount( - "(.*\\{)|(\\})", - boost::regex_constants::perl - ); - std::string count = boost::regex_replace( pM, regCount, "" ); - - boost::regex regExtent( - "\\{.*\\}", - boost::regex_constants::perl - ); - std::string extent = boost::regex_replace( pM, regExtent, "" ); - - // no count {n} given (implies one) - if( count == *iter ) - count = "1"; - - const SubdomainPair g = { - boost::lexical_cast< uint32_t > ( extent ), - boost::lexical_cast< uint32_t > ( count ) - }; - newInput.emplace_back( g ); - } - - return newInput; - } + parse( std::string const s ) const; };