Example #1
0
    Status Resolver::resolveRelativePathsStartingAddresses(
            const vector<Address>&  relativePathAddresses,
            Mask&                   mask,
            vector<BrowsePath>&     results,
            vector<Status>&         statuses)
    {
        // declare the return status
        Status ret(statuscodes::Good);

        // declare the number of relative paths
        size_t noOfRelativePaths = relativePathAddresses.size();

        // resize the output parameters
        results.resize(noOfRelativePaths);
        statuses.resize(noOfRelativePaths);

        // fill a vector containing all starting addresses
        vector<Address> startingAddresses;
        for (size_t i = 0; i < noOfRelativePaths && ret.isGood(); i++)
        {
            if (mask.isSet(i))
                startingAddresses.push_back(*(relativePathAddresses[i].getStartingAddress()));
        }

        // resolve them (recursively!)
        vector<ExpandedNodeId>  startingAddressesResults;
        vector<Status>          startingAddressesStatuses;
        ret = resolve(startingAddresses, startingAddressesResults, startingAddressesStatuses);

        // update the results
        for (size_t i = 0, j = 0; i < noOfRelativePaths && ret.isGood(); i++)
        {
            if (mask.isSet(i))
            {
                // update the results
                results[i].startingExpandedNodeId = startingAddressesResults[j];
                results[i].relativePath           = relativePathAddresses[i].getRelativePath();

                // update the statuses
                statuses[i] = startingAddressesStatuses[j];

                // update the mask (only resolved starting addresses should be processed further!)
                if (statuses[i].isNotGood())
                    mask.unset(i);

                // increment the index of the startingAddressesResults
                j++;
            }
        }

        return ret;
    }
Example #2
0
    /**
     * Add Exchange in GridBuffer memory space.
     *
     * An Exchange is added to this GridBuffer. The exchange buffers use
     * the same memory as this GridBuffer.
     *
     * @param dataPlace place where received data are stored [GUARD | BORDER]
     *        if dataPlace=GUARD than copy other BORDER to my GUARD
     *        if dataPlace=BORDER than copy other GUARD to my BORDER
     * @param receive a Mask which describes the directions for the exchange
     * @param guardingCells number of guarding cells in each dimension
     * @param sizeOnDevice if true, internal buffers have their size information on the device, too
     */
    void addExchange(uint32_t dataPlace, const Mask &receive, DataSpace<DIM> guardingCells, uint32_t communicationTag, bool sizeOnDevice = false)
    {

        if (hasOneExchange && (communicationTag != lastUsedCommunicationTag))
            throw std::runtime_error("It is not allowed to give the same GridBuffer different communicationTags");

        lastUsedCommunicationTag = communicationTag;

        receiveMask = receiveMask + receive;
        sendMask = this->receiveMask.getMirroredMask();
        Mask send = receive.getMirroredMask();



        for (uint32_t ex = 1; ex< -12 * (int) DIM + 6 * (int) DIM * (int) DIM + 9; ++ex)
        {
            if (send.isSet(ex))
            {
                uint32_t uniqCommunicationTag = (communicationTag << 5) | ex;

                if (!hasOneExchange && !privateGridBuffer::UniquTag::getInstance().isTagUniqu(uniqCommunicationTag))
                {
                    std::stringstream message;
                    message << "unique exchange communication tag ("
                        << uniqCommunicationTag << ") witch is created from communicationTag ("
                        << communicationTag << ") allready used for other gridbuffer exchange";
                    throw std::runtime_error(message.str());
                }
                hasOneExchange = true;

                if (sendExchanges[ex] != NULL)
                {
                    throw std::runtime_error("Exchange already added!");
                }
                //std::cout<<"Add Exchange: send="<<ex<<" receive="<<Mask::getMirroredExchangeType((ExchangeType)ex)<<std::endl;
                maxExchange = std::max(maxExchange, ex + 1u);
                sendExchanges[ex] = new ExchangeIntern<BORDERTYPE, DIM > (*deviceBuffer, gridLayout, guardingCells,
                                                                          (ExchangeType) ex, uniqCommunicationTag,
                                                                          dataPlace == GUARD ? BORDER : GUARD, sizeOnDevice);
                ExchangeType recvex = Mask::getMirroredExchangeType(ex);
                maxExchange = std::max(maxExchange, recvex + 1u);
                receiveExchanges[recvex] =
                    new ExchangeIntern<BORDERTYPE, DIM > (
                                                          *deviceBuffer,
                                                          gridLayout,
                                                          guardingCells,
                                                          recvex,
                                                          uniqCommunicationTag,
                                                          dataPlace == GUARD ? GUARD : BORDER,
                                                          sizeOnDevice);
            }
        }
    }
Example #3
0
    /**
     * Add Exchange in dedicated memory space.
     *
     * An Exchange is added to this GridBuffer. The exchange buffers use
     * the their own memory instead of using the GridBuffer's memory space.
     *
     * @param receive a Mask which describes the directions for the exchange
     * @param dataSpace size of the newly created exchange buffer in each dimension
     * @param sizeOnDevice if true, internal buffers have their size information on the device, too
     */
    void addExchangeBuffer(const Mask &receive, const DataSpace<DIM> &dataSpace, uint32_t communicationTag, bool sizeOnDevice = false)
    {

        if (hasOneExchange && (communicationTag != lastUsedCommunicationTag))
            throw std::runtime_error("It is not allowed to give the same GridBuffer different communicationTags");
        lastUsedCommunicationTag = communicationTag;


        /*don't create buffer with 0 (zero) elements*/
        if (dataSpace.productOfComponents() != 0)
        {
            receiveMask = receiveMask + receive;
            sendMask = this->receiveMask.getMirroredMask();
            Mask send = receive.getMirroredMask();
            for (uint32_t ex = 1; ex < 27; ++ex)
            {
                if (send.isSet(ex))
                {
                    uint32_t uniqCommunicationTag = (communicationTag << 5) | ex;
                    if (!hasOneExchange && !privateGridBuffer::UniquTag::getInstance().isTagUniqu(uniqCommunicationTag))
                    {
                        std::stringstream message;
                        message << "unique exchange communication tag ("
                            << uniqCommunicationTag << ") witch is created from communicationTag ("
                            << communicationTag << ") allready used for other gridbuffer exchange";
                        throw std::runtime_error(message.str());
                    }
                    hasOneExchange = true;

                    if (sendExchanges[ex] != NULL)
                    {
                        throw std::runtime_error("Exchange already added!");
                    }

                    //GridLayout<DIM> memoryLayout(size);
                    maxExchange = std::max(maxExchange, ex + 1u);
                    sendExchanges[ex] = new ExchangeIntern<BORDERTYPE, DIM > (/*memoryLayout*/ dataSpace,
                                                                              ex, uniqCommunicationTag, sizeOnDevice);

                    ExchangeType recvex = Mask::getMirroredExchangeType(ex);
                    maxExchange = std::max(maxExchange, recvex + 1u);
                    receiveExchanges[recvex] = new ExchangeIntern<BORDERTYPE, DIM > (/*memoryLayout*/ dataSpace,
                                                                                     recvex, uniqCommunicationTag, sizeOnDevice);
                }
            }
        }
    }
Example #4
0
    Status Resolver::verifyExpandedNodeIds(
            const vector<Address>&  addresses,
            const Mask&             mask,
            vector<ExpandedNodeId>& results,
            vector<Status>&         resultStatuses)
    {
        logger_->debug("Now verifying %d ExpandedNodeIds", addresses.size());

        Status ret(statuscodes::Good);

        // verify the 'set' targets
        for (size_t i = 0; i < addresses.size() && ret.isGood(); i++)
        {
            if (mask.isSet(i))
            {
                // copy the ExpandedNodeId
                results[i] = addresses[i].getExpandedNodeId();

                // set the status
                if (results[i].hasServerUri())
                {
                    if (   results[i].nodeId().hasNameSpaceIndex() \
                        || results[i].nodeId().hasNameSpaceUri())
                    {
                        database_->addressCache.add(addresses[i], results[i]);
                        resultStatuses[i] = statuscodes::Good;
                    }
                    else
                    {
                        ret = NoNamespaceIndexOrUriGivenError();
                    }
                }
                else
                {
                    ret = EmptyServerUriError();
                }
            }
        }

        return ret;
    }
Example #5
0
    Status Resolver::resolveRelativePaths(
            const vector<Address>&  addresses,
            const Mask&             mask,
            vector<ExpandedNodeId>& results,
            vector<Status>&         statuses)
    {
        // declare the return status
        Status ret;

        // declare a vector of browse paths which we will try to translate into ExpandedNodeIds
        vector<BrowsePath> browsePaths;

        // declare a mask that will indicate which browse paths still need to be translated
        Mask remainingMask = mask;

        // first try to resolve the starting addresses (all at once!)
        // the 'remainingMask', 'browsePaths' and 'statuses' will be updated!
        ret = resolveRelativePathsStartingAddresses(
                addresses,
                remainingMask,
                browsePaths,
                statuses);

        // now try to resolve the relative paths (essentially browse paths since their starting
        // addresses have been resolved)
        if (ret.isGood())
            ret = resolveBrowsePaths(browsePaths, remainingMask, results, statuses);

        // add the resolved addresses to the cache
        for (size_t i = 0; i < addresses.size() && ret.isGood(); i++)
        {
            if (mask.isSet(i) && statuses[i].isGood())
            {
                database_->addressCache.add(addresses[i], results[i], true);
            }
        }

        return ret;
    }
Example #6
0
    // Resolve a relative path (which may span over multiple server address spaces!)
    //==============================================================================================
    Status Resolver::resolveBrowsePaths(
            vector<BrowsePath>&       browsePaths,
            Mask&                     mask,
            vector<ExpandedNodeId>&   results,
            vector<Status>&           statuses)
    {
        logger_->debug("Resolving %d browse paths", browsePaths.size());

        // declare the return status
        Status ret;

        // declare the number of browsePaths
        size_t noOfBrowsePaths = browsePaths.size();

        // resize the output arguments
        results.resize(noOfBrowsePaths);
        statuses.resize(noOfBrowsePaths);

        // check if the mask has the correct size
        if (mask.size() != noOfBrowsePaths)
        {
            ret = UnexpectedError("Mask does not have the correct size!");
        }
        else if (mask.setCount() == 0)
        {
            logger_->debug("Nothing to do, no browse paths are marked with the mask");
        }
        else
        {
            // create a request and a result
            TranslateBrowsePathsToNodeIdsRequest request;
            TranslateBrowsePathsToNodeIdsResult  result;

            for (size_t i = 0; i < noOfBrowsePaths; i++)
            {
                if (mask.isSet(i))
                    request.targets.push_back(
                            TranslateBrowsePathsToNodeIdsRequestTarget(browsePaths[i]));
            }

            ret = sessionFactory_->invokeRequest<TranslateBrowsePathsToNodeIdsService>(
                    request,
                    Mask(request.targets.size(), true),
                    result);

            if (ret.isGood())
            {
                // fill the remainingBrowsePaths and remainingMask
                for (size_t i = 0, j = 0; i < noOfBrowsePaths; i++)
                {
                    if (mask.isSet(i))
                    {
                        processBrowsePathsResolutionResultTarget(
                                result.targets[j], i, browsePaths, mask, results, statuses);

                        // increment the counter for the 'set' results
                        j++;
                    }
                }

                // check if we need to perform another (recursive!) translation
                if (mask.setCount() > 0)
                    ret = resolveBrowsePaths(browsePaths, mask, results, statuses);
            }
        }

        return ret;
    }