From 75b17ffda17aadcd1992c93184b4094a536c628d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Widera?= Date: Tue, 19 Feb 2019 16:41:37 +0100 Subject: [PATCH] split `ParserGridDistribution` into `hpp/cpp` file fix #2898 Split the grid parser into a interface file `hpp` and the implementation `cpp` to avoid that boost regex is parsed by nvcc. Boost regex is very often the root of compile issues because nvcc is not able to split the host and device part correctly. --- .../initialization/ParserGridDistribution.cpp | 142 ++++++++++++++++++ .../initialization/ParserGridDistribution.hpp | 109 +------------- 2 files changed, 148 insertions(+), 103 deletions(-) create mode 100644 include/picongpu/initialization/ParserGridDistribution.cpp 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; };