<commit_before>#include "bufferAgent.h"

using boost::shared_ptr;
using boost::thread;
using boost::bind;

using std::string;

namespace veil {
namespace helpers {

BufferAgent::BufferAgent(write_fun w, read_fun r)
  : m_agentActive(false),
    doWrite(w),
    doRead(r)
{
    agentStart();
}
BufferAgent::~BufferAgent()
{
    agentStop();
}

int BufferAgent::onOpen(std::string path, ffi_type ffi)
{
    unique_lock guard(m_loopMutex);
    m_cacheMap.erase(ffi->fh_old);

    buffer_ptr lCache(new LockableCache());
    lCache->fileName = path;
    lCache->buffer = newFileCache();
    lCache->ffi = *ffi;

    m_cacheMap[ffi->fh_old] = lCache;

    return 0;
}

int BufferAgent::onWrite(std::string path, const std::string &buf, size_t size, off_t offset, ffi_type ffi)
{
    unique_lock guard(m_loopMutex);
        buffer_ptr wrapper = m_cacheMap[ffi->fh_old];
    guard.release();

    unique_lock buff_guard(wrapper->mutex);

    while(wrapper->buffer->byteSize() > 1024 * 1024 * 10) {
        wrapper->cond.wait(buff_guard);
    }

    wrapper->buffer->writeData(offset, buf);

    guard.lock();
    m_jobQueue.push_back(ffi->fh_old);

    return EOPNOTSUPP;
}

int BufferAgent::onRead(std::string path, std::string &buf, size_t size, off_t offset, ffi_type ffi)
{
    boost::unique_lock<boost::recursive_mutex> guard(m_loopMutex);
    return EOPNOTSUPP;
}

int BufferAgent::onFlush(std::string path, ffi_type ffi)
{
    unique_lock guard(m_loopMutex);
        buffer_ptr wrapper = m_cacheMap[ffi->fh_old];
    guard.release();

    unique_lock buff_guard(wrapper->mutex);

    while(wrapper->buffer->blockCount() > 0)
    {
        block_ptr block = wrapper->buffer->removeOldestBlock();
        int res = doWrite(wrapper->fileName, block->data, block->data.size(), block->offset, &wrapper->ffi);
        if(res < 0)
        {
            while(wrapper->buffer->blockCount() > 0)
            {
                (void) wrapper->buffer->removeOldestBlock();
            }
            return res;
        }
    }

    guard.lock();
    m_jobQueue.remove(ffi->fh_old);

    return 0;
}

int BufferAgent::onRelease(std::string path, ffi_type ffi)
{
    boost::unique_lock<boost::recursive_mutex> guard(m_loopMutex);
    m_cacheMap.erase(ffi->fh_old);

    return 0;
}

void BufferAgent::agentStart(int worker_count)
{
    m_workers.clear();
    m_agentActive = true;

    while(worker_count--)
    {
        m_workers.push_back(shared_ptr<thread>(new thread(bind(&BufferAgent::workerLoop, this))));
    }
}

void BufferAgent::agentStop()
{
    m_agentActive = false;
    while(m_workers.size() > 0)
    {
        m_workers.back()->join();
        m_workers.pop_back();
    }
}

void BufferAgent::workerLoop()
{
    unique_lock guard(m_loopMutex);
    while(m_agentActive)
    {
        while(m_jobQueue.empty())
            m_loopCond.wait(guard);

        fd_type file = m_jobQueue.front();
        buffer_ptr wrapper = m_cacheMap[file];
        m_jobQueue.pop_front();
        m_loopCond.notify_all();

        if(!wrapper)
            continue;

        {
            guard.release();

            unique_lock buff_guard(wrapper->mutex);

            block_ptr block = wrapper->buffer->removeOldestBlock();
            int res = doWrite(wrapper->fileName, block->data, block->data.size(), block->offset, file);

            wrapper->cond.notify_all();

            guard.lock();
            if(wrapper->buffer->blockCount() > 0)
            {
                m_jobQueue.push_back(file);
            }
        }

    }
}

boost::shared_ptr<FileCache> BufferAgent::newFileCache()
{
    return boost::shared_ptr<FileCache>(new FileCache(100 * 1024));
}

} // namespace helpers
} // namespace veil

<commit_msg>VFS-292: debug<commit_after>#include "bufferAgent.h"

using boost::shared_ptr;
using boost::thread;
using boost::bind;

using std::string;

namespace veil {
namespace helpers {

BufferAgent::BufferAgent(write_fun w, read_fun r)
  : m_agentActive(false),
    doWrite(w),
    doRead(r)
{
    agentStart();
}
BufferAgent::~BufferAgent()
{
    agentStop();
}

int BufferAgent::onOpen(std::string path, ffi_type ffi)
{
    unique_lock guard(m_loopMutex);
    m_cacheMap.erase(ffi->fh_old);

    buffer_ptr lCache(new LockableCache());
    lCache->fileName = path;
    lCache->buffer = newFileCache();
    lCache->ffi = *ffi;

    m_cacheMap[ffi->fh_old] = lCache;

    return 0;
}

int BufferAgent::onWrite(std::string path, const std::string &buf, size_t size, off_t offset, ffi_type ffi)
{
    unique_lock guard(m_loopMutex);
        buffer_ptr wrapper = m_cacheMap[ffi->fh_old];
    guard.release();

    unique_lock buff_guard(wrapper->mutex);

    while(wrapper->buffer->byteSize() > 1024 * 1024 * 10) {
        wrapper->cond.wait(buff_guard);
    }

    wrapper->buffer->writeData(offset, buf);

    guard.lock();
    m_jobQueue.push_back(ffi->fh_old);

    return EOPNOTSUPP;
}

int BufferAgent::onRead(std::string path, std::string &buf, size_t size, off_t offset, ffi_type ffi)
{
    boost::unique_lock<boost::recursive_mutex> guard(m_loopMutex);
    return EOPNOTSUPP;
}

int BufferAgent::onFlush(std::string path, ffi_type ffi)
{
    unique_lock guard(m_loopMutex);
        buffer_ptr wrapper = m_cacheMap[ffi->fh_old];
    guard.release();

    unique_lock buff_guard(wrapper->mutex);

    while(wrapper->buffer->blockCount() > 0)
    {
        block_ptr block = wrapper->buffer->removeOldestBlock();
        int res = doWrite(wrapper->fileName, block->data, block->data.size(), block->offset, &wrapper->ffi);
        if(res < 0)
        {
            while(wrapper->buffer->blockCount() > 0)
            {
                (void) wrapper->buffer->removeOldestBlock();
            }
            return res;
        }
    }

    guard.lock();
    m_jobQueue.remove(ffi->fh_old);

    return 0;
}

int BufferAgent::onRelease(std::string path, ffi_type ffi)
{
    boost::unique_lock<boost::recursive_mutex> guard(m_loopMutex);
    m_cacheMap.erase(ffi->fh_old);

    return 0;
}

void BufferAgent::agentStart(int worker_count)
{
    m_workers.clear();
    m_agentActive = true;

    while(worker_count--)
    {
        m_workers.push_back(shared_ptr<thread>(new thread(bind(&BufferAgent::workerLoop, this))));
    }
}

void BufferAgent::agentStop()
{
    m_agentActive = false;
    while(m_workers.size() > 0)
    {
        m_workers.back()->join();
        m_workers.pop_back();
    }
}

void BufferAgent::workerLoop()
{
    unique_lock guard(m_loopMutex);
    while(m_agentActive)
    {
        while(m_jobQueue.empty())
            m_loopCond.wait(guard);

        fd_type file = m_jobQueue.front();
        buffer_ptr wrapper = m_cacheMap[file];
        m_jobQueue.pop_front();
        m_loopCond.notify_all();

        if(!wrapper)
            continue;

        {
            guard.release();

            unique_lock buff_guard(wrapper->mutex);

            block_ptr block = wrapper->buffer->removeOldestBlock();
            int res = doWrite(wrapper->fileName, block->data, block->data.size(), block->offset, &wrapper->ffi);

            wrapper->cond.notify_all();

            guard.lock();
            if(wrapper->buffer->blockCount() > 0)
            {
                m_jobQueue.push_back(file);
            }
        }

    }
}

boost::shared_ptr<FileCache> BufferAgent::newFileCache()
{
    return boost::shared_ptr<FileCache>(new FileCache(100 * 1024));
}

} // namespace helpers
} // namespace veil

<|endoftext|>


<commit_before>#include "bufferAgent.h"

using boost::shared_ptr;
using boost::thread;
using boost::bind;

using std::string;

namespace veil {
namespace helpers {

BufferAgent::BufferAgent(write_fun w, read_fun r)
  : m_agentActive(false),
    doWrite(w),
    doRead(r)
{
    agentStart();
}
BufferAgent::~BufferAgent()
{
    agentStop();
}

int BufferAgent::onOpen(std::string path, ffi_type ffi)
{
    unique_lock guard(m_loopMutex);
    m_cacheMap.erase(ffi->fh);

    buffer_ptr lCache(new LockableCache());
    lCache->fileName = path;
    lCache->buffer = newFileCache();
    lCache->ffi = *ffi;

    m_cacheMap[ffi->fh] = lCache;

    return 0;
}

int BufferAgent::onWrite(std::string path, const std::string &buf, size_t size, off_t offset, ffi_type ffi)
{
    unique_lock guard(m_loopMutex);
        buffer_ptr wrapper = m_cacheMap[ffi->fh];
    guard.unlock();

    {
        unique_lock buff_guard(wrapper->mutex);

        while(wrapper->buffer->byteSize() > 1024 * 1024 * 64) {
            guard.lock();
                m_jobQueue.push_front(ffi->fh);
                m_loopCond.notify_all();
            guard.unlock();
            wrapper->cond.wait(buff_guard);
        }

        wrapper->buffer->writeData(offset, buf);
    }

    guard.lock();
    m_jobQueue.push_back(ffi->fh);
    m_loopCond.notify_all();

    return size;
}

int BufferAgent::onRead(std::string path, std::string &buf, size_t size, off_t offset, ffi_type ffi)
{
    boost::unique_lock<boost::recursive_mutex> guard(m_loopMutex);
    return EOPNOTSUPP;
}

int BufferAgent::onFlush(std::string path, ffi_type ffi)
{
    unique_lock guard(m_loopMutex);
        buffer_ptr wrapper = m_cacheMap[ffi->fh];
    guard.unlock();

    unique_lock buff_guard(wrapper->mutex);

    while(wrapper->buffer->blockCount() > 0)
    {
        block_ptr block = wrapper->buffer->removeOldestBlock();
        int res = doWrite(wrapper->fileName, block->data, block->data.size(), block->offset, &wrapper->ffi);
        if(res < 0)
        {
            while(wrapper->buffer->blockCount() > 0)
            {
                (void) wrapper->buffer->removeOldestBlock();
            }
            return res;
        }
    }

    guard.lock();
    m_jobQueue.remove(ffi->fh);

    return 0;
}

int BufferAgent::onRelease(std::string path, ffi_type ffi)
{
    boost::unique_lock<boost::recursive_mutex> guard(m_loopMutex);
    m_cacheMap.erase(ffi->fh);
    m_jobQueue.remove(ffi->fh);

    return 0;
}

void BufferAgent::agentStart(int worker_count)
{
    m_workers.clear();
    m_agentActive = true;

    while(worker_count--)
    {
        m_workers.push_back(shared_ptr<thread>(new thread(bind(&BufferAgent::workerLoop, this))));
    }
}

void BufferAgent::agentStop()
{
    m_agentActive = false;
    m_loopCond.notify_all();
    while(m_workers.size() > 0)
    {
        m_workers.back()->join();
        m_workers.pop_back();
    }
}

void BufferAgent::workerLoop()
{
    unique_lock guard(m_loopMutex);
    while(m_agentActive)
    {
        while(m_jobQueue.empty() && m_agentActive)
            m_loopCond.wait(guard);

        if(!m_agentActive)
            return;

        fd_type file = m_jobQueue.front();
        buffer_ptr wrapper = m_cacheMap[file];
        m_jobQueue.pop_front();
        m_loopCond.notify_all();

        if(!wrapper)
            continue;

        guard.unlock();

        {
            unique_lock sendGuard(wrapper->sendMutex);

            block_ptr block;
            {
                unique_lock buff_guard(wrapper->mutex);
                block = wrapper->buffer->removeOldestBlock();
            }

            if(block)
            {
                int res = doWrite(wrapper->fileName, block->data, block->data.size(), block->offset, &wrapper->ffi);

                wrapper->cond.notify_all();
            }

            {
                unique_lock buff_guard(wrapper->mutex);
                guard.lock();
                if(wrapper->buffer->blockCount() > 0)
                {
                    m_jobQueue.push_back(file);
                }
            }
        }

        wrapper->cond.notify_all();
    }
}

boost::shared_ptr<FileCache> BufferAgent::newFileCache()
{
    return boost::shared_ptr<FileCache>(new FileCache(1024 * 1024));
}

} // namespace helpers
} // namespace veil

<commit_msg>VFS-292: debug<commit_after>#include "bufferAgent.h"

using boost::shared_ptr;
using boost::thread;
using boost::bind;

using std::string;

namespace veil {
namespace helpers {

BufferAgent::BufferAgent(write_fun w, read_fun r)
  : m_agentActive(false),
    doWrite(w),
    doRead(r)
{
    agentStart();
}
BufferAgent::~BufferAgent()
{
    agentStop();
}

int BufferAgent::onOpen(std::string path, ffi_type ffi)
{
    unique_lock guard(m_loopMutex);
    m_cacheMap.erase(ffi->fh);

    buffer_ptr lCache(new LockableCache());
    lCache->fileName = path;
    lCache->buffer = newFileCache();
    lCache->ffi = *ffi;

    m_cacheMap[ffi->fh] = lCache;

    return 0;
}

int BufferAgent::onWrite(std::string path, const std::string &buf, size_t size, off_t offset, ffi_type ffi)
{
    unique_lock guard(m_loopMutex);
        buffer_ptr wrapper = m_cacheMap[ffi->fh];
    guard.unlock();

    {
        unique_lock buff_guard(wrapper->mutex);

        while(wrapper->buffer->byteSize() > 1024 * 1024 * 64) {
            guard.lock();
                m_jobQueue.push_front(ffi->fh);
                m_loopCond.notify_all();
            guard.unlock();
            wrapper->cond.wait(buff_guard);
        }

        wrapper->buffer->writeData(offset, buf);
    }

    guard.lock();
    m_jobQueue.push_back(ffi->fh);
    m_loopCond.notify_all();

    return size;
}

int BufferAgent::onRead(std::string path, std::string &buf, size_t size, off_t offset, ffi_type ffi)
{
    boost::unique_lock<boost::recursive_mutex> guard(m_loopMutex);
    return EOPNOTSUPP;
}

int BufferAgent::onFlush(std::string path, ffi_type ffi)
{
    unique_lock guard(m_loopMutex);
        buffer_ptr wrapper = m_cacheMap[ffi->fh];
    guard.unlock();

    unique_lock buff_guard(wrapper->mutex);

    while(wrapper->buffer->blockCount() > 0)
    {
        block_ptr block = wrapper->buffer->removeOldestBlock();
        int res = doWrite(wrapper->fileName, block->data, block->data.size(), block->offset, &wrapper->ffi);
        if(res < 0)
        {
            while(wrapper->buffer->blockCount() > 0)
            {
                (void) wrapper->buffer->removeOldestBlock();
            }
            return res;
        }
    }

    guard.lock();
    m_jobQueue.remove(ffi->fh);

    return 0;
}

int BufferAgent::onRelease(std::string path, ffi_type ffi)
{
    boost::unique_lock<boost::recursive_mutex> guard(m_loopMutex);
    m_cacheMap.erase(ffi->fh);
    m_jobQueue.remove(ffi->fh);

    return 0;
}

void BufferAgent::agentStart(int worker_count)
{
    m_workers.clear();
    m_agentActive = true;

    while(worker_count--)
    {
        m_workers.push_back(shared_ptr<thread>(new thread(bind(&BufferAgent::workerLoop, this))));
    }
}

void BufferAgent::agentStop()
{
    m_agentActive = false;
    m_loopCond.notify_all();
    while(m_workers.size() > 0)
    {
        m_workers.back()->join();
        m_workers.pop_back();
    }
}

void BufferAgent::workerLoop()
{
    unique_lock guard(m_loopMutex);
    while(m_agentActive)
    {
        while(m_jobQueue.empty() && m_agentActive)
            m_loopCond.wait(guard);

        if(!m_agentActive)
            return;

        fd_type file = m_jobQueue.front();
        buffer_ptr wrapper = m_cacheMap[file];
        m_jobQueue.pop_front();
        m_loopCond.notify_all();

        if(!wrapper)
            continue;

        guard.unlock();

        {
            unique_lock sendGuard(wrapper->sendMutex);

            block_ptr block;
            {
                unique_lock buff_guard(wrapper->mutex);
                block = wrapper->buffer->removeOldestBlock();
            }

            if(block)
            {
                //int res = doWrite(wrapper->fileName, block->data, block->data.size(), block->offset, &wrapper->ffi);

                wrapper->cond.notify_all();
            }

            {
                unique_lock buff_guard(wrapper->mutex);
                guard.lock();
                if(wrapper->buffer->blockCount() > 0)
                {
                    m_jobQueue.push_back(file);
                }
            }
        }

        wrapper->cond.notify_all();
    }
}

boost::shared_ptr<FileCache> BufferAgent::newFileCache()
{
    return boost::shared_ptr<FileCache>(new FileCache(1024 * 1024));
}

} // namespace helpers
} // namespace veil

<|endoftext|>


<commit_before>// Copyright 2014 Vinzenz Feenstra
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GUARD_PYPA_AST_TREE_WALKER_HH_INCLUDED
#define GUARD_PYPA_AST_TREE_WALKER_HH_INCLUDED

#include <pypa/ast/visitor.hh>
#include <type_traits>

namespace pypa {

template< typename AstT, typename F >
void walk_tree(AstT & t, F f, int depth = 0);

namespace detail {
    template< typename F >
    struct tree_walk_visitor {
        struct each {
            F * f_;
            int depth_;
            each(F * f, int depth) : f_(f), depth_(depth) {}

            void next(Ast & t) {
                visit(detail::tree_walk_visitor<F>(f_, depth_ + 1), t);
            }

            template< typename T >
            void next(std::shared_ptr<T> t) {
                if(t) visit(detail::tree_walk_visitor<F>(f_, depth_ + 1), *t);
            }

            template< typename T >
            void next(T) {}

            template< typename T >
            bool operator() (T t) {
                if((*f_)(t)) {
                    next(t);
                    return true;
                }
                return false;
            }

            template< typename T >
            void operator() (std::vector<T> & t) {
                for(auto & e : t) {
                    next(e);
                }
            }
        };

        F * f_;
        int depth_;
        tree_walk_visitor(F * f, int depth) : f_(f), depth_(depth){}
        template< typename T >
        void operator() (T  t) {
            ast_member_visit<AstIDByType<T>::Id>::apply(t, each(f_, depth_ + 1));
        }
    };
}

template< typename AstT, typename F >
void walk_tree(AstT & t, F f, int depth = 0) {
    visit(detail::tree_walk_visitor<F>(&f, depth), t);
}

template< typename AstT, typename F >
void walk_tree(std::vector<AstT> & t, F f, int depth = 0) {
    for(auto & e : t) {
        visit(detail::tree_walk_visitor<F>(&f, depth), e);
    }
}

}

#endif //GUARD_PYPA_AST_TREE_WALKER_HH_INCLUDED
<commit_msg>Do not redefine the default argument<commit_after>// Copyright 2014 Vinzenz Feenstra
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GUARD_PYPA_AST_TREE_WALKER_HH_INCLUDED
#define GUARD_PYPA_AST_TREE_WALKER_HH_INCLUDED

#include <pypa/ast/visitor.hh>
#include <type_traits>

namespace pypa {

template< typename AstT, typename F >
void walk_tree(AstT & t, F f, int depth = 0);

namespace detail {
    template< typename F >
    struct tree_walk_visitor {
        struct each {
            F * f_;
            int depth_;
            each(F * f, int depth) : f_(f), depth_(depth) {}

            void next(Ast & t) {
                visit(detail::tree_walk_visitor<F>(f_, depth_ + 1), t);
            }

            template< typename T >
            void next(std::shared_ptr<T> t) {
                if(t) visit(detail::tree_walk_visitor<F>(f_, depth_ + 1), *t);
            }

            template< typename T >
            void next(T) {}

            template< typename T >
            bool operator() (T t) {
                if((*f_)(t)) {
                    next(t);
                    return true;
                }
                return false;
            }

            template< typename T >
            void operator() (std::vector<T> & t) {
                for(auto & e : t) {
                    next(e);
                }
            }
        };

        F * f_;
        int depth_;
        tree_walk_visitor(F * f, int depth) : f_(f), depth_(depth){}
        template< typename T >
        void operator() (T  t) {
            ast_member_visit<AstIDByType<T>::Id>::apply(t, each(f_, depth_ + 1));
        }
    };
}

template< typename AstT, typename F >
void walk_tree(AstT & t, F f, int depth) {
    visit(detail::tree_walk_visitor<F>(&f, depth), t);
}

template< typename AstT, typename F >
void walk_tree(std::vector<AstT> & t, F f, int depth = 0) {
    for(auto & e : t) {
        visit(detail::tree_walk_visitor<F>(&f, depth), e);
    }
}

}

#endif //GUARD_PYPA_AST_TREE_WALKER_HH_INCLUDED
<|endoftext|>


<commit_before>#pragma once

#include <cstdint>
#include <ostream>

class int48_t final {
    public:
        // default constructors
        int48_t() : _s0(0), _s1(0), _s2(0) {}
        int48_t(const int48_t& obj) = default;
        int48_t(int48_t&& obj) noexcept = default;

        // converter constructors
        int48_t(const std::int64_t i) {
            int64_to_int48(i, *this);
        }

        // default assigments
        int48_t& operator=(const int48_t& obj) = default;
        int48_t& operator=(int48_t&& obj) noexcept = default;

        // converter assigments
        int48_t& operator=(std::int64_t i) {
            int64_to_int48(i, *this);
            return *this;
        }

        // cast operators
        operator std::int64_t() const {
            return int48_to_int64(*this);
        }

        // comparison
        bool operator==(const int48_t& obj) const {
            return (_s0 == obj._s0) && (_s1 == obj._s1) && (_s2 == obj._s2);
        }

        bool operator!=(const int48_t& obj) const {
            return (_s0 != obj._s0) || (_s1 != obj._s1) || (_s2 != obj._s2);
        }

        bool operator==(const std::int64_t i) const {
            // XXX: implement fast path
            return i == int48_to_int64(*this);
        }

        bool operator!=(const std::int64_t i) const {
            // XXX: implement fast path
            return i != int48_to_int64(*this);
        }

        // printing
        friend std::ostream& operator<<(std::ostream& stream, const int48_t& obj);

    private:
        union converter64 {
            std::uint64_t u;
            std::int64_t  i;
        };

        std::uint16_t _s0;  // least significant byte
        std::uint16_t _s1;  // middle byte
        std::uint16_t _s2;  // most significant 7 bit + sign bit (which is the most significant bit)

        // converter code
        static void int64_to_int48(const std::int64_t i64, int48_t& i48) {
            converter64 c;
            c.i = i64;

            i48._s0 = static_cast<std::uint16_t>(
                  ((c.u      ) & static_cast<std::uint64_t>(0xffff))
            );

            i48._s1 = static_cast<std::uint16_t>(
                  ((c.u >> 16) & static_cast<std::uint64_t>(0xffff))
            );

            i48._s2 = static_cast<std::uint16_t>(
                  ((c.u >> 32) & static_cast<std::uint64_t>(0x7fff))  // 7 bit content
                | ((c.u >> 48) & static_cast<std::uint64_t>(0x8000))  // sign bit
            );
        }

        static std::int64_t int48_to_int64(const int48_t& i48) {
            converter64 c;
            c.u = 0;

            c.u |= static_cast<std::uint64_t>(i48._s0);

            c.u |= static_cast<std::uint64_t>(i48._s1) << 16;

            c.u |= (static_cast<std::uint64_t>(i48._s2) & static_cast<std::uint64_t>(0x7fff)) << 32;

            // recover sign bit
            if (static_cast<std::uint64_t>(i48._s2) & static_cast<std::uint64_t>(0x8000)) {
                // fill remaining bits
                c.u |= 0xffff800000000000;
            }

            return c.i;
        }
};

static_assert(sizeof(int48_t) == 6, "size of int48_t is not 48bit, check your compiler!");

std::ostream& operator<<(std::ostream& stream, const int48_t& obj) {
    stream << "int48_t(s0=" << obj._s0 << ", s1=" << obj._s1 << ", s2=" << obj._s2 << ")";
    return stream;
}
<commit_msg>implement uint64_t conversion<commit_after>#pragma once

#include <cstdint>
#include <ostream>

class int48_t final {
    public:
        // default constructors
        int48_t() : _s0(0), _s1(0), _s2(0) {}
        int48_t(const int48_t& obj) = default;
        int48_t(int48_t&& obj) noexcept = default;

        // converter constructors
        int48_t(const std::int64_t i) {
            int64_to_int48(i, *this);
        }

        int48_t(const std::uint64_t i) {
            int64_to_int48(static_cast<std::int64_t>(i), *this);
        }

        // default assigments
        int48_t& operator=(const int48_t& obj) = default;
        int48_t& operator=(int48_t&& obj) noexcept = default;

        // converter assigments
        int48_t& operator=(std::int64_t i) {
            int64_to_int48(i, *this);
            return *this;
        }

        int48_t& operator=(std::uint64_t i) {
            int64_to_int48(static_cast<std::int64_t>(i), *this);
            return *this;
        }

        // cast operators
        operator std::int64_t() const {
            return int48_to_int64(*this);
        }

        operator std::uint64_t() const {
            return static_cast<std::uint64_t>(int48_to_int64(*this));
        }

        // comparison
        bool operator==(const int48_t& obj) const {
            return (_s0 == obj._s0) && (_s1 == obj._s1) && (_s2 == obj._s2);
        }

        bool operator!=(const int48_t& obj) const {
            return (_s0 != obj._s0) || (_s1 != obj._s1) || (_s2 != obj._s2);
        }

        bool operator==(const std::int64_t i) const {
            // XXX: implement fast path
            return i == int48_to_int64(*this);
        }

        bool operator!=(const std::int64_t i) const {
            // XXX: implement fast path
            return i != int48_to_int64(*this);
        }

        // printing
        friend std::ostream& operator<<(std::ostream& stream, const int48_t& obj);

    private:
        union converter64 {
            std::uint64_t u;
            std::int64_t  i;
        };

        std::uint16_t _s0;  // least significant byte
        std::uint16_t _s1;  // middle byte
        std::uint16_t _s2;  // most significant 7 bit + sign bit (which is the most significant bit)

        // converter code
        static void int64_to_int48(const std::int64_t i64, int48_t& i48) {
            converter64 c;
            c.i = i64;

            i48._s0 = static_cast<std::uint16_t>(
                  ((c.u      ) & static_cast<std::uint64_t>(0xffff))
            );

            i48._s1 = static_cast<std::uint16_t>(
                  ((c.u >> 16) & static_cast<std::uint64_t>(0xffff))
            );

            i48._s2 = static_cast<std::uint16_t>(
                  ((c.u >> 32) & static_cast<std::uint64_t>(0x7fff))  // 7 bit content
                | ((c.u >> 48) & static_cast<std::uint64_t>(0x8000))  // sign bit
            );
        }

        static std::int64_t int48_to_int64(const int48_t& i48) {
            converter64 c;
            c.u = 0;

            c.u |= static_cast<std::uint64_t>(i48._s0);

            c.u |= static_cast<std::uint64_t>(i48._s1) << 16;

            c.u |= (static_cast<std::uint64_t>(i48._s2) & static_cast<std::uint64_t>(0x7fff)) << 32;

            // recover sign bit
            if (static_cast<std::uint64_t>(i48._s2) & static_cast<std::uint64_t>(0x8000)) {
                // fill remaining bits
                c.u |= 0xffff800000000000;
            }

            return c.i;
        }
};

static_assert(sizeof(int48_t) == 6, "size of int48_t is not 48bit, check your compiler!");

std::ostream& operator<<(std::ostream& stream, const int48_t& obj) {
    stream << "int48_t(s0=" << obj._s0 << ", s1=" << obj._s1 << ", s2=" << obj._s2 << ")";
    return stream;
}
<|endoftext|>


<commit_before>//===------------------------- cxa_exception.cpp --------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//
//  This file implements the "Exception Handling APIs"
//  http://mentorembedded.github.io/cxx-abi/abi-eh.html
//
//===----------------------------------------------------------------------===//

// Support functions for the no-exceptions libc++ library

#include "cxxabi.h"

#include <exception>        // for std::terminate
#include "cxa_exception.hpp"
#include "cxa_handlers.hpp"

namespace __cxxabiv1 {

extern "C" {

void
__cxa_increment_exception_refcount(void *thrown_object) throw() {
    if (thrown_object != nullptr)
        std::terminate();
}

void
__cxa_decrement_exception_refcount(void *thrown_object) throw() {
    if (thrown_object != nullptr)
      std::terminate();
}

void *__cxa_current_primary_exception() throw() { return nullptr; }

void
__cxa_rethrow_primary_exception(void* thrown_object) {
    if (thrown_object != nullptr)
      std::terminate();
}

bool
__cxa_uncaught_exception() throw() { return false; }

unsigned int
__cxa_uncaught_exceptions() throw() { return 0; }

}  // extern "C"

}  // abi
<commit_msg>Blind attempt to fix linker errors when building libc++abit w/o exceptions.<commit_after>//===------------------------- cxa_exception.cpp --------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//
//  This file implements the "Exception Handling APIs"
//  http://mentorembedded.github.io/cxx-abi/abi-eh.html
//
//===----------------------------------------------------------------------===//

// Support functions for the no-exceptions libc++ library

#include "cxxabi.h"

#include <exception>        // for std::terminate
#include "cxa_exception.hpp"
#include "cxa_handlers.hpp"

namespace __cxxabiv1 {

extern "C" {

void
__cxa_increment_exception_refcount(void *thrown_object) throw() {
    if (thrown_object != nullptr)
        std::terminate();
}

void
__cxa_decrement_exception_refcount(void *thrown_object) throw() {
    if (thrown_object != nullptr)
      std::terminate();
}

void *__cxa_current_primary_exception() throw() { return nullptr; }

void
__cxa_rethrow_primary_exception(void* thrown_object) {
    if (thrown_object != nullptr)
      std::terminate();
}

bool
__cxa_uncaught_exception() throw() { return false; }

unsigned int
__cxa_uncaught_exceptions() throw() { return 0; }

}  // extern "C"

// provide dummy implementations for the 'no exceptions' case.
uint64_t __getExceptionClass  (const _Unwind_Exception*)           { return 0; }
void     __setExceptionClass  (      _Unwind_Exception*, uint64_t) {}
bool     __isOurExceptionClass(const _Unwind_Exception*)           { return false; }

}  // abi
<|endoftext|>


<commit_before>/*
 *  Copyright (C) 2010 - 2015 Leonid Kostrykin
 *
 *  Chair of Medical Engineering (mediTEC)
 *  RWTH Aachen University
 *  Pauwelsstr. 20
 *  52074 Aachen
 *  Germany
 *
 */

#include <Carna/qt/SpatialListModel.h>
#include <Carna/qt/SpatialListModelDetails.h>
#include <Carna/base/CarnaException.h>
#include <Carna/base/Node.h>
#include <Carna/base/Spatial.h>
#include <QTimer>

namespace Carna
{

namespace qt
{

// ----------------------------------------------------------------------------------
// SpatialListModel :: Details
// ----------------------------------------------------------------------------------

SpatialListModel::Details::Details( SpatialListModel& self )
    : self( self )
    , spatialMapper( nullptr )
    , root( nullptr )
    , invalidated( false )
{
}

void SpatialListModel::Details::removeRootListener()
{
    if( root != nullptr )
    {
        root->removeNodeListener( *this );
    }
}

void SpatialListModel::Details::onNodeDelete( const base::Node& node )
{
    CARNA_ASSERT( &node == root );

    /* We do not use 'removeRootListener' here because we are not allowed to remove
     * the listener from that dying node.
     */
    root = nullptr;
}

void SpatialListModel::Details::onTreeChange( base::Node& node, bool inThisSubtree )
{
    if( inThisSubtree )
    {
        invalidate();
    }
}

void SpatialListModel::Details::onTreeInvalidated( base::Node& subtree )
{
}

void SpatialListModel::Details::invalidate()
{
    if( !invalidated )
    {
        invalidated = true;
        QTimer::singleShot( 0, this, SLOT( update() ) );
    }
}

void SpatialListModel::Details::update()
{
    invalidated = false;
    const std::size_t previousCount = spatials.size();
    spatials.clear();
    if( root != nullptr )
    {
        CARNA_ASSERT( spatialMapper != nullptr );
        const SpatialMapper& map = *spatialMapper;

        /* Gather objects avoiding duplicates.
         */
        std::set< base::Spatial* > set;
        root->visitChildren( true, [&map, &set]( base::Spatial& spatial )
            {
                base::Spatial* const mapped = map( spatial );
                if( mapped != nullptr )
                {
                    set.insert( mapped );
                }
            }
        );

        /* Finish the update.
         */
        spatials = std::vector< base::Spatial* >( set.begin(), set.end() );
        const std::size_t affectedRows = std::max( previousCount, spatials.size() );
        emit self.dataChanged( self.index( 0, 0 ), self.index( affectedRows - 1, 0 ) );
    }
}

// ----------------------------------------------------------------------------------
// pickMovableSpatial
// ----------------------------------------------------------------------------------

static base::Spatial* pickMovableSpatial( base::Spatial& spatial )
{
    if( spatial.isMovable() )
    {
        return &spatial;
    }
    else
    if( spatial.hasParent() )
    {
        return pickMovableSpatial( spatial.parent() );
    }
    else
    {
        return nullptr;
    }
}

// ----------------------------------------------------------------------------------
// pickMovableGeometry
// ----------------------------------------------------------------------------------

static base::Spatial* pickMovableGeometry( base::Spatial& spatial )
{
    if( dynamic_cast< base::Geometry* >( &spatial ) != nullptr )
    {
        return pickMovableSpatial( spatial );
    }
    else
    {
        return nullptr;
    }
}

// ----------------------------------------------------------------------------------
// SpatialListModel
// ----------------------------------------------------------------------------------

const SpatialListModel::SpatialMapper SpatialListModel::PICK_MOVABLE_GEOMETRY = &pickMovableGeometry;

SpatialListModel::SpatialListModel( const SpatialMapper& spatialMapper )
    : pimpl( new Details( *this ) )
{
    setSpatialMapper( spatialMapper );
}

SpatialListModel::SpatialListModel( base::Node& root, const SpatialMapper& spatialMapper )
    : pimpl( new Details( *this ) )
{
    setSpatialMapper( spatialMapper );
    setRoot( root );
}

SpatialListModel::~SpatialListModel()
{
    pimpl->removeRootListener();
}

void SpatialListModel::setSpatialMapper( const SpatialMapper& spatialMapper )
{
    if( pimpl->spatialMapper != &spatialMapper )
    {
        pimpl->spatialMapper = &spatialMapper;
        pimpl->invalidate();
    }
}

void SpatialListModel::setRoot( base::Node& root )
{
    if( pimpl->root != &root )
    {
        pimpl->removeRootListener();
        pimpl->root = &root;
        root.addNodeListener( *pimpl );
        pimpl->invalidate();
    }
}

std::size_t SpatialListModel::spatials() const
{
    return pimpl->spatials.size();
}

base::Spatial& SpatialListModel::spatialAt( std::size_t index )
{
    CARNA_ASSERT( index < spatials() );
    return *pimpl->spatials[ index ];
}

const base::Spatial& SpatialListModel::spatialAt( std::size_t index ) const
{
    CARNA_ASSERT( index < spatials() );
    return *pimpl->spatials[ index ];
}

int SpatialListModel::rowCount( const QModelIndex& parent ) const
{
    return spatials();
}

QVariant SpatialListModel::data( const QModelIndex& index, int role ) const
{
    const base::Spatial& spatial = spatialAt( index.row() );
    switch( role )
    {

    case Qt::DisplayRole:
        return spatial.tag().empty() ? QString( "Unknown Object" ) : QString::fromStdString( spatial.tag() );

    /*
    case Qt::DecorationRole:
        return QIcon( "" );
        */

    default:
        return QVariant();

    }
}

}  // namespace Carna :: qt

}  // namespace Carna

<commit_msg>Fixed bug in SpatialListModel.<commit_after>/*
 *  Copyright (C) 2010 - 2015 Leonid Kostrykin
 *
 *  Chair of Medical Engineering (mediTEC)
 *  RWTH Aachen University
 *  Pauwelsstr. 20
 *  52074 Aachen
 *  Germany
 *
 */

#include <Carna/qt/SpatialListModel.h>
#include <Carna/qt/SpatialListModelDetails.h>
#include <Carna/base/CarnaException.h>
#include <Carna/base/Node.h>
#include <Carna/base/Spatial.h>
#include <QTimer>

namespace Carna
{

namespace qt
{

// ----------------------------------------------------------------------------------
// SpatialListModel :: Details
// ----------------------------------------------------------------------------------

SpatialListModel::Details::Details( SpatialListModel& self )
    : self( self )
    , spatialMapper( nullptr )
    , root( nullptr )
    , invalidated( false )
{
}

void SpatialListModel::Details::removeRootListener()
{
    if( root != nullptr )
    {
        root->removeNodeListener( *this );
    }
}

void SpatialListModel::Details::onNodeDelete( const base::Node& node )
{
    CARNA_ASSERT( &node == root );

    /* We do not use 'removeRootListener' here because we are not allowed to remove
     * the listener from that dying node.
     */
    root = nullptr;

    /* Invalidate explicitly here because 'onTreeChange' will not get notified.
     */
    invalidate();
}

void SpatialListModel::Details::onTreeChange( base::Node& node, bool inThisSubtree )
{
    if( inThisSubtree )
    {
        invalidate();
    }
}

void SpatialListModel::Details::onTreeInvalidated( base::Node& subtree )
{
}

void SpatialListModel::Details::invalidate()
{
    if( !invalidated )
    {
        invalidated = true;
        QTimer::singleShot( 0, this, SLOT( update() ) );
    }
}

void SpatialListModel::Details::update()
{
    invalidated = false;
    const std::size_t previousCount = spatials.size();
    spatials.clear();
    if( root != nullptr )
    {
        CARNA_ASSERT( spatialMapper != nullptr );
        const SpatialMapper& map = *spatialMapper;

        /* Gather objects avoiding duplicates.
         */
        std::set< base::Spatial* > set;
        root->visitChildren( true, [&map, &set]( base::Spatial& spatial )
            {
                base::Spatial* const mapped = map( spatial );
                if( mapped != nullptr )
                {
                    set.insert( mapped );
                }
            }
        );

        /* Finish the update.
         */
        spatials = std::vector< base::Spatial* >( set.begin(), set.end() );
        const std::size_t affectedRows = std::max( previousCount, spatials.size() );
        emit self.dataChanged( self.index( 0, 0 ), self.index( affectedRows - 1, 0 ) );
    }
}

// ----------------------------------------------------------------------------------
// pickMovableSpatial
// ----------------------------------------------------------------------------------

static base::Spatial* pickMovableSpatial( base::Spatial& spatial )
{
    if( spatial.isMovable() )
    {
        return &spatial;
    }
    else
    if( spatial.hasParent() )
    {
        return pickMovableSpatial( spatial.parent() );
    }
    else
    {
        return nullptr;
    }
}

// ----------------------------------------------------------------------------------
// pickMovableGeometry
// ----------------------------------------------------------------------------------

static base::Spatial* pickMovableGeometry( base::Spatial& spatial )
{
    if( dynamic_cast< base::Geometry* >( &spatial ) != nullptr )
    {
        return pickMovableSpatial( spatial );
    }
    else
    {
        return nullptr;
    }
}

// ----------------------------------------------------------------------------------
// SpatialListModel
// ----------------------------------------------------------------------------------

const SpatialListModel::SpatialMapper SpatialListModel::PICK_MOVABLE_GEOMETRY = &pickMovableGeometry;

SpatialListModel::SpatialListModel( const SpatialMapper& spatialMapper )
    : pimpl( new Details( *this ) )
{
    setSpatialMapper( spatialMapper );
}

SpatialListModel::SpatialListModel( base::Node& root, const SpatialMapper& spatialMapper )
    : pimpl( new Details( *this ) )
{
    setSpatialMapper( spatialMapper );
    setRoot( root );
}

SpatialListModel::~SpatialListModel()
{
    pimpl->removeRootListener();
}

void SpatialListModel::setSpatialMapper( const SpatialMapper& spatialMapper )
{
    if( pimpl->spatialMapper != &spatialMapper )
    {
        pimpl->spatialMapper = &spatialMapper;
        pimpl->invalidate();
    }
}

void SpatialListModel::setRoot( base::Node& root )
{
    if( pimpl->root != &root )
    {
        pimpl->removeRootListener();
        pimpl->root = &root;
        root.addNodeListener( *pimpl );
        pimpl->invalidate();
    }
}

std::size_t SpatialListModel::spatials() const
{
    return pimpl->spatials.size();
}

base::Spatial& SpatialListModel::spatialAt( std::size_t index )
{
    CARNA_ASSERT( index < spatials() );
    return *pimpl->spatials[ index ];
}

const base::Spatial& SpatialListModel::spatialAt( std::size_t index ) const
{
    CARNA_ASSERT( index < spatials() );
    return *pimpl->spatials[ index ];
}

int SpatialListModel::rowCount( const QModelIndex& parent ) const
{
    return spatials();
}

QVariant SpatialListModel::data( const QModelIndex& index, int role ) const
{
    const base::Spatial& spatial = spatialAt( index.row() );
    switch( role )
    {

    case Qt::DisplayRole:
        return spatial.tag().empty() ? QString( "Unknown Object" ) : QString::fromStdString( spatial.tag() );

    /*
    case Qt::DecorationRole:
        return QIcon( "" );
        */

    default:
        return QVariant();

    }
}

}  // namespace Carna :: qt

}  // namespace Carna

<|endoftext|>


<commit_before>/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/core/framework/common_shape_fns.h"
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/rng_alg.h"

namespace tensorflow {

using shape_inference::DimensionHandle;
using shape_inference::InferenceContext;
using shape_inference::ShapeHandle;

static Status StatelessShapeV2(InferenceContext* c) {
  // Check key and counter shapes
  ShapeHandle key;
  ShapeHandle counter;
  TF_RETURN_IF_ERROR(c->WithRank(c->input(1), 1, &key));
  TF_RETURN_IF_ERROR(c->WithRank(c->input(2), 1, &counter));
  shape_inference::ShapeHandle unused_shape;
  TF_RETURN_IF_ERROR(c->WithRank(c->input(3), 0, &unused_shape));
  DimensionHandle unused;
  TF_RETURN_IF_ERROR(c->WithValue(c->Dim(key, 0), RNG_KEY_SIZE, &unused));

  // Set output shape
  ShapeHandle out;
  TF_RETURN_IF_ERROR(c->MakeShapeFromShapeTensor(0, &out));
  c->set_output(0, out);
  return Status::OK();
}

#define REGISTER_STATELESS_OP(name)                           \
  REGISTER_OP(name)                                           \
      .Input("shape: Tshape")                                 \
      .Input("key: uint64")                                   \
      .Input("counter: uint64")                               \
      .Input("alg: int32")                                    \
      .Output("output: dtype")                                \
      .Attr("dtype: {half,bfloat16,float,double} = DT_FLOAT") \
      .Attr("Tshape: {int32, int64} = DT_INT32")              \
      .SetShapeFn(StatelessShapeV2)

REGISTER_STATELESS_OP("StatelessRandomUniformV2");
REGISTER_STATELESS_OP("StatelessRandomNormalV2");
REGISTER_STATELESS_OP("StatelessTruncatedNormalV2");

#undef REGISTER_STATELESS_OP

REGISTER_OP("StatelessRandomUniformIntV2")
    .Input("shape: Tshape")
    .Input("key: uint64")
    .Input("counter: uint64")
    .Input("alg: int32")
    .Input("minval: dtype")
    .Input("maxval: dtype")
    .Output("output: dtype")
    .Attr("dtype: {int32, int64, uint32, uint64}")
    .Attr("Tshape: {int32, int64} = DT_INT32")
    .SetShapeFn([](InferenceContext* c) {
      ShapeHandle unused;
      Status s = c->WithRank(c->input(4), 0, &unused);
      if (!s.ok()) {
        return errors::InvalidArgument(
            "minval must be a scalar; got a tensor of shape ",
            c->DebugString(c->input(4)));
      }
      s = c->WithRank(c->input(5), 0, &unused);
      if (!s.ok()) {
        return errors::InvalidArgument(
            "maxval must be a scalar; got a tensor of shape ",
            c->DebugString(c->input(5)));
      }
      return StatelessShapeV2(c);
    });

REGISTER_OP("StatelessRandomUniformFullIntV2")
    .Input("shape: Tshape")
    .Input("key: uint64")
    .Input("counter: uint64")
    .Input("alg: int32")
    .Output("output: dtype")
    .Attr("dtype: {int32, int64, uint32, uint64} = DT_UINT64")
    .Attr("Tshape: {int32, int64} = DT_INT32")
    .SetShapeFn(StatelessShapeV2);

REGISTER_OP("StatelessRandomGetKeyCounterAlg")
    .Input("seed: Tseed")
    .Output("key: uint64")
    .Output("counter: uint64")
    .Output("alg: int32")
    .Attr("Tseed: {int32, int64} = DT_INT64")
    .SetShapeFn([](InferenceContext* c) {
      // Check seed shape
      ShapeHandle seed;
      TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 1, &seed));
      DimensionHandle unused;
      TF_RETURN_IF_ERROR(c->WithValue(c->Dim(seed, 0), 2, &unused));

      // Set output shapes
      c->set_output(0, c->MakeShape({RNG_KEY_SIZE}));
      c->set_output(1, c->MakeShape({RNG_MAX_COUNTER_SIZE}));
      c->set_output(2, c->MakeShape({}));
      return Status::OK();
    });

REGISTER_OP("StatelessRandomGetKeyCounter")
    .Input("seed: Tseed")
    .Output("key: uint64")
    .Output("counter: uint64")
    .Attr("Tseed: {int32, int64} = DT_INT64")
    .SetIsStateful()  // because outputs depend on device
    .SetShapeFn([](InferenceContext* c) {
      // Check seed shape
      ShapeHandle seed;
      TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 1, &seed));
      DimensionHandle unused;
      TF_RETURN_IF_ERROR(c->WithValue(c->Dim(seed, 0), 2, &unused));

      // Set output shapes
      c->set_output(0, c->MakeShape({RNG_KEY_SIZE}));
      c->set_output(1, c->MakeShape({RNG_MAX_COUNTER_SIZE}));
      return Status::OK();
    });

REGISTER_OP("StatelessRandomGetAlg")
    .Output("alg: int32")
    .SetIsStateful()  // because outputs depend on device
    .SetShapeFn([](InferenceContext* c) {
      c->set_output(0, c->MakeShape({}));
      return Status::OK();
    });

}  // namespace tensorflow
<commit_msg>Removes the `SetIsStateful` mark on op `StatelessRandomGetKeyCounter` (the mark causes problems in tf.data iterator checkpointing).<commit_after>/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/core/framework/common_shape_fns.h"
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/rng_alg.h"

namespace tensorflow {

using shape_inference::DimensionHandle;
using shape_inference::InferenceContext;
using shape_inference::ShapeHandle;

static Status StatelessShapeV2(InferenceContext* c) {
  // Check key and counter shapes
  ShapeHandle key;
  ShapeHandle counter;
  TF_RETURN_IF_ERROR(c->WithRank(c->input(1), 1, &key));
  TF_RETURN_IF_ERROR(c->WithRank(c->input(2), 1, &counter));
  shape_inference::ShapeHandle unused_shape;
  TF_RETURN_IF_ERROR(c->WithRank(c->input(3), 0, &unused_shape));
  DimensionHandle unused;
  TF_RETURN_IF_ERROR(c->WithValue(c->Dim(key, 0), RNG_KEY_SIZE, &unused));

  // Set output shape
  ShapeHandle out;
  TF_RETURN_IF_ERROR(c->MakeShapeFromShapeTensor(0, &out));
  c->set_output(0, out);
  return Status::OK();
}

#define REGISTER_STATELESS_OP(name)                           \
  REGISTER_OP(name)                                           \
      .Input("shape: Tshape")                                 \
      .Input("key: uint64")                                   \
      .Input("counter: uint64")                               \
      .Input("alg: int32")                                    \
      .Output("output: dtype")                                \
      .Attr("dtype: {half,bfloat16,float,double} = DT_FLOAT") \
      .Attr("Tshape: {int32, int64} = DT_INT32")              \
      .SetShapeFn(StatelessShapeV2)

REGISTER_STATELESS_OP("StatelessRandomUniformV2");
REGISTER_STATELESS_OP("StatelessRandomNormalV2");
REGISTER_STATELESS_OP("StatelessTruncatedNormalV2");

#undef REGISTER_STATELESS_OP

REGISTER_OP("StatelessRandomUniformIntV2")
    .Input("shape: Tshape")
    .Input("key: uint64")
    .Input("counter: uint64")
    .Input("alg: int32")
    .Input("minval: dtype")
    .Input("maxval: dtype")
    .Output("output: dtype")
    .Attr("dtype: {int32, int64, uint32, uint64}")
    .Attr("Tshape: {int32, int64} = DT_INT32")
    .SetShapeFn([](InferenceContext* c) {
      ShapeHandle unused;
      Status s = c->WithRank(c->input(4), 0, &unused);
      if (!s.ok()) {
        return errors::InvalidArgument(
            "minval must be a scalar; got a tensor of shape ",
            c->DebugString(c->input(4)));
      }
      s = c->WithRank(c->input(5), 0, &unused);
      if (!s.ok()) {
        return errors::InvalidArgument(
            "maxval must be a scalar; got a tensor of shape ",
            c->DebugString(c->input(5)));
      }
      return StatelessShapeV2(c);
    });

REGISTER_OP("StatelessRandomUniformFullIntV2")
    .Input("shape: Tshape")
    .Input("key: uint64")
    .Input("counter: uint64")
    .Input("alg: int32")
    .Output("output: dtype")
    .Attr("dtype: {int32, int64, uint32, uint64} = DT_UINT64")
    .Attr("Tshape: {int32, int64} = DT_INT32")
    .SetShapeFn(StatelessShapeV2);

REGISTER_OP("StatelessRandomGetKeyCounterAlg")
    .Input("seed: Tseed")
    .Output("key: uint64")
    .Output("counter: uint64")
    .Output("alg: int32")
    .Attr("Tseed: {int32, int64} = DT_INT64")
    .SetShapeFn([](InferenceContext* c) {
      // Check seed shape
      ShapeHandle seed;
      TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 1, &seed));
      DimensionHandle unused;
      TF_RETURN_IF_ERROR(c->WithValue(c->Dim(seed, 0), 2, &unused));

      // Set output shapes
      c->set_output(0, c->MakeShape({RNG_KEY_SIZE}));
      c->set_output(1, c->MakeShape({RNG_MAX_COUNTER_SIZE}));
      c->set_output(2, c->MakeShape({}));
      return Status::OK();
    });

REGISTER_OP("StatelessRandomGetKeyCounter")
    .Input("seed: Tseed")
    .Output("key: uint64")
    .Output("counter: uint64")
    .Attr("Tseed: {int32, int64} = DT_INT64")
    .SetShapeFn([](InferenceContext* c) {
      // Check seed shape
      ShapeHandle seed;
      TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 1, &seed));
      DimensionHandle unused;
      TF_RETURN_IF_ERROR(c->WithValue(c->Dim(seed, 0), 2, &unused));

      // Set output shapes
      c->set_output(0, c->MakeShape({RNG_KEY_SIZE}));
      c->set_output(1, c->MakeShape({RNG_MAX_COUNTER_SIZE}));
      return Status::OK();
    });

REGISTER_OP("StatelessRandomGetAlg")
    .Output("alg: int32")
    .SetIsStateful()  // because outputs depend on device
    .SetShapeFn([](InferenceContext* c) {
      c->set_output(0, c->MakeShape({}));
      return Status::OK();
    });

}  // namespace tensorflow
<|endoftext|>


<commit_before>#include "rosplan_planning_system/POPFEsterelPlanParser.h"

/* implementation of rosplan_planning_system::POPFEsterelPlanParser.h */
namespace KCL_rosplan {

	/* constructor */
	POPFEsterelPlanParser::POPFEsterelPlanParser(ros::NodeHandle &nh) : node_handle(&nh)
	{
		// knowledge interface
		update_knowledge_client = nh.serviceClient<rosplan_knowledge_msgs::KnowledgeUpdateService>("/kcl_rosplan/update_knowledge_base");
	}

	void POPFEsterelPlanParser::reset() {
		plan_nodes.clear();
		plan_edges.clear();
	}

	void POPFEsterelPlanParser::generateFilter(PlanningEnvironment &environment) {
		// do nothing yet
	}

	void POPFEsterelPlanParser::toLowerCase(std::string &str) {
		std::transform(str.begin(), str.end(), str.begin(), tolower);
	}

	/*------------*/
	/* parse PDDL */
	/*------------*/

	/**
	 * parse a PDDL condition
	 */
	void POPFEsterelPlanParser::preparePDDLConditions(StrlNode &node, PlanningEnvironment &environment) {

		std::string normalised_action_name = node.dispatch_msg.name;
		std::transform(normalised_action_name.begin(), normalised_action_name.end(), normalised_action_name.begin(), tolower);

		// find action conditions
		std::map<std::string, std::vector<std::vector<std::string> > >::iterator oit;
		oit = environment.domain_operator_precondition_map.find(normalised_action_name);
		if(oit==environment.domain_operator_precondition_map.end()) {
			std::cerr << "action precondition map entry not found:" << node.dispatch_msg.name << std::endl;
			for (std::map<std::string, std::vector<std::vector<std::string> > >::const_iterator ci = environment.domain_operator_precondition_map.begin(); ci != environment.domain_operator_precondition_map.end(); ++ci)
			{
				std::cerr << (*ci).first;
				const std::vector<std::vector<std::string> >& mapping = (*ci).second;
				for (std::vector<std::vector<std::string> >::const_iterator ci = mapping.begin(); ci != mapping.end(); ++ci)
				{
					const std::vector<std::string>& list = *ci;
					std::cerr << "{";
					for (std::vector<std::string>::const_iterator ci = list.begin(); ci != list.end(); ++ci)
					{
						std::cerr << *ci << ", ";
					}
					std::cerr << "}" << std::endl;
				}
			}
			exit(1);
			return;
		}

		std::vector<rosplan_knowledge_msgs::KnowledgeItem> processed_preconditions;

		// iterate through conditions
		for(std::vector<std::vector<std::string> >::iterator cit = oit->second.begin(); cit!=oit->second.end(); cit++) {

			rosplan_knowledge_msgs::KnowledgeItem condition;
			condition.is_negative = false;

			// set fact or function
			std::map<std::string,std::vector<std::string> >::iterator dit = environment.domain_predicates.find((*cit)[0]);
			if(dit!=environment.domain_predicates.end()) condition.knowledge_type = rosplan_knowledge_msgs::KnowledgeItem::FACT;

			dit = environment.domain_functions.find((*cit)[0]);
			if(dit!=environment.domain_functions.end()) condition.knowledge_type = rosplan_knowledge_msgs::KnowledgeItem::FUNCTION;

			// create edge name
			condition.attribute_name = (*cit)[0];

			std::stringstream ss;
			ss << condition.attribute_name;

			// populate parameters
			int index = 1;

			for(std::vector<std::string>::iterator pit = environment.domain_predicates[condition.attribute_name].begin(); pit!=environment.domain_predicates[condition.attribute_name].end(); pit++) {

				// set parameter label to predicate label
				diagnostic_msgs::KeyValue param;
				param.key = *pit;

				// find label as it is in domain operator
				std::string conditionKey = (*cit)[index];
				std::transform(conditionKey.begin(), conditionKey.end(), conditionKey.begin(), tolower);
				index++;

				// set value
				std::vector<diagnostic_msgs::KeyValue>::iterator opit;
				for(opit = node.dispatch_msg.parameters.begin(); opit!=node.dispatch_msg.parameters.end(); opit++) {

					std::string parameter = opit->key;
					std::transform(parameter.begin(), parameter.end(), parameter.begin(), tolower);

					if(0==parameter.compare(conditionKey)) {
						param.value = opit->value;
						ss << " " << param.value;
					}
				}
				condition.values.push_back(param);
			}

			// Make sure we haven't already processed this precondition.
			bool already_processed = true;
			for (std::vector<rosplan_knowledge_msgs::KnowledgeItem>::const_iterator ci = processed_preconditions.begin(); ci != processed_preconditions.end(); ++ci)
			{
				const rosplan_knowledge_msgs::KnowledgeItem& processed_precondition = *ci;
				if (condition.attribute_name != processed_precondition.attribute_name)
				{
					already_processed = false;
					break;
				}

				for (unsigned int i = 0; i < processed_precondition.values.size(); ++i)
				{
					if (processed_precondition.values[i].value != condition.values[i].value)
					{
						already_processed = false;
						break;
					}
				}
			}

			if (already_processed) continue;

			// create new edge
			StrlEdge* edge = new StrlEdge();
			edge->signal_type = CONDITION;
			edge->edge_name = ss.str();
			edge->active = false;
			edge->sinks.push_back(&node);
			edge->external_conditions.push_back(condition);

			node.input.push_back(edge);
			plan_edges.push_back(edge);
		}
	}

	/*------------*/
	/* Parse plan */
	/*------------*/

	void POPFEsterelPlanParser::createNodeAndEdge(const std::string& action_name, double dispatchTime, double duration, int node_id, PlanningEnvironment &environment, StrlNode& node, StrlEdge& edge) {

		node.node_name = action_name;
		node.node_id = node_id;
		node.dispatched = false;
		node.completed = false;

		// save this parent edge
		edge.signal_type = ACTION;
		std::stringstream ss;
		ss << "e" << node.node_id;
		edge.edge_name = ss.str();
		edge.sources.push_back(&node);
		edge.active = false;
		plan_edges.push_back(&edge);

		// prepare message
		node.output.push_back(&edge);
		node.dispatch_msg.action_id = node.node_id;
		node.dispatch_msg.duration = duration;
		node.dispatch_msg.dispatch_time = dispatchTime;
		node.dispatch_msg.name = action_name;

		// check for parameters
		int curr = 0;
		int next = 0;
		bool paramsExist = (action_name.find(" ",curr) != std::string::npos);
		if(paramsExist) {

			// name
			next = action_name.find(" ",curr);
			node.dispatch_msg.name = action_name.substr(curr,next-curr).c_str();

			// parameters
			int parameter_index = 0;
			std::vector<std::string> params;
			while(next < action_name.length()) {
				curr = next + 1;
				next = action_name.find(" ",curr);
				if(next == std::string::npos)
					next = action_name.length();

				diagnostic_msgs::KeyValue pair;
				pair.key = environment.domain_operators[node.dispatch_msg.name][parameter_index];
				pair.value = action_name.substr(curr,next-curr);
				node.dispatch_msg.parameters.push_back(pair);
				++parameter_index;
			}
		}

		preparePDDLConditions(node, environment);
		plan_nodes.push_back(&node);
		action_list.push_back(node.dispatch_msg);
	}

	/**
	 * Parse a plan written by POPF
	 */
	void POPFEsterelPlanParser::preparePlan(std::string &dataPath, PlanningEnvironment &environment, size_t freeActionID) {

		ROS_INFO("KCL: (POPFEsterelPlanParser) Loading plan from file: %s. Initial action ID: %zu", ((dataPath + "plan.pddl").c_str()), freeActionID);

		// load plan file
		StrlEdge* last_edge = NULL;
		std::ifstream infile((dataPath + "plan.pddl").c_str());
		int curr,next,nodeCount;
		std::string line;
		double expectedPlanDuration = 0;
		bool planFound = false;
		bool planRead = false;

		while(!infile.eof()) {

			std::getline(infile, line);
			toLowerCase(line);

			if (line.substr(0,6).compare("; Plan") == 0) {

				// prepare plan
				plan_nodes.clear();
				plan_edges.clear();
				action_list.clear();
				expectedPlanDuration = atof(line.substr(25).c_str());
				planFound = true;
				planRead = false;

				// The last edge that will lead to the next action.
				last_edge = NULL;

			} else if (line.substr(0,6).compare("; Time")!=0) {
				//consume useless lines

			} else if (!planRead) {

				nodeCount = freeActionID;
				std::vector<std::string> parentEdge;

				while(!infile.eof() && line.compare("")!=0) {

					std::getline(infile, line);
					toLowerCase(line);

					// 0.000: (goto_waypoint kenny wp0 wp1)  [10.000]
					if (line.length()<2)
						break;

					// dispatchTime
					curr=line.find(":");
					double dispatchTime = (double)atof(line.substr(0,curr).c_str());

					// action
					next=line.find(")",curr);
					std::string name = line.substr(curr,next-curr).c_str();

					// duration
					curr=line.find("[",curr)+1;
					next=line.find("]",curr);
					double duration = (double)atof(line.substr(curr,next-curr).c_str());

					{
						StrlNode* node = new StrlNode();
						StrlEdge* edge = new StrlEdge();
						createNodeAndEdge(name, dispatchTime, duration, nodeCount, environment, *node, *edge);
						++nodeCount;

						if (last_edge != NULL)
						{
							node->input.push_back(last_edge);
							last_edge->sinks.push_back(node);
						}
						last_edge = edge;
					}
				}
				planRead = true;
			}
		}
		// printPlan(plan);
		produceEsterel();
		infile.close();
	}

	/*-----------------*/
	/* Produce Esterel */
	/*-----------------*/

	/*
	 * output a plan as an Esterel controller
	 */
	bool POPFEsterelPlanParser::produceEsterel() {

		// output file
		std::string strl_file;
		ros::NodeHandle nh("~");
		nh.param("strl_file_path", strl_file, std::string("common/plan.strl"));

		ROS_INFO("KCL: (POPFEsterelPlanParser) Write the esterel plan: %s", strl_file.c_str());

		std::ofstream dest;
		dest.open(strl_file.c_str());

		// main module
		dest << "module plan:" << std::endl;

		// inputs
		dest << "input SOURCE";
		std::vector<StrlNode*>::iterator nit = plan_nodes.begin();
		for(; nit!=plan_nodes.end(); nit++) {
			dest << ", a" << (*nit)->node_id << "_complete";
		}
		dest << std::endl;

		// outputs
		dest << "output SINK";
		for(nit = plan_nodes.begin(); nit!=plan_nodes.end(); nit++) {
			dest << ", a" << (*nit)->node_id << "_dispatch";
		}
		dest << std::endl;

		// internal signals
		std::vector<StrlEdge*>::iterator eit = plan_edges.begin();
		if(eit!=plan_edges.end()) {
			dest << "signal " << (*eit)->edge_name;
			for(; eit!=plan_edges.end(); eit++) {
				dest << ", " << (*eit)->edge_name;
			}
			dest << " in" << std::endl;
		}

		// run everything
		nit = plan_nodes.begin();
		if(nit!=plan_nodes.end()) {
			dest << "run action" << (*nit)->node_id << std::endl;
			for(; nit!=plan_nodes.end(); nit++) {
				dest << " || action" << (*nit)->node_id << std::endl;
			}
			dest << "end" << std::endl;
		}
		dest << "end module" << std::endl << std::endl;

		// action modules
		nit = plan_nodes.begin();
		for(; nit!=plan_nodes.end(); nit++) {

			dest << "module action" << (*nit)->node_id << ":" << std::endl;

			if((*nit)->input.size() > 0) {
				dest << "input ";
				for(int j=0;j<(*nit)->input.size();j++) {
					if(j>0) dest << ", ";
					dest << (*nit)->input[j]->edge_name;
				}
				dest << ";" << std::endl;
			}

			if((*nit)->output.size() > 0) {
				dest << "output ";
				for(int j=0;j<(*nit)->output.size();j++) {
					if(j>0) dest << ", ";
					dest << (*nit)->output[j]->edge_name;
				}
				dest << ";" << std::endl;
			}

			if((*nit)->input.size() > 0) {
				dest << "  await ";
				for(int j=0;j<(*nit)->input.size();j++) {
					if(j>0) dest << " or ";
					dest << (*nit)->input[j]->edge_name;
				}
				dest << ";" << std::endl;
			}

			dest << "  emit a" << (*nit)->node_id << "_dispatch;" << std::endl;
			dest << "  await a" << (*nit)->node_id << "_complete;" << std::endl;

			for(int j=0;j<(*nit)->output.size();j++) {
				dest << "emit " << (*nit)->output[j]->edge_name;
			}
			dest << ";" << std::endl;
			dest << "end module" << std::endl << std::endl;
		}
		dest.close();
	}
} // close namespace
<commit_msg>fixed string parsing bug in POPFEsterelPlanParser<commit_after>#include "rosplan_planning_system/POPFEsterelPlanParser.h"

/* implementation of rosplan_planning_system::POPFEsterelPlanParser.h */
namespace KCL_rosplan {

	/* constructor */
	POPFEsterelPlanParser::POPFEsterelPlanParser(ros::NodeHandle &nh) : node_handle(&nh)
	{
		// knowledge interface
		update_knowledge_client = nh.serviceClient<rosplan_knowledge_msgs::KnowledgeUpdateService>("/kcl_rosplan/update_knowledge_base");
	}

	void POPFEsterelPlanParser::reset() {
		plan_nodes.clear();
		plan_edges.clear();
	}

	void POPFEsterelPlanParser::generateFilter(PlanningEnvironment &environment) {
		// do nothing yet
	}

	void POPFEsterelPlanParser::toLowerCase(std::string &str) {
		std::transform(str.begin(), str.end(), str.begin(), tolower);
	}

	/*------------*/
	/* parse PDDL */
	/*------------*/

	/**
	 * parse a PDDL condition
	 */
	void POPFEsterelPlanParser::preparePDDLConditions(StrlNode &node, PlanningEnvironment &environment) {

		std::string normalised_action_name = node.dispatch_msg.name;
		std::transform(normalised_action_name.begin(), normalised_action_name.end(), normalised_action_name.begin(), tolower);

		// find action conditions
		std::map<std::string, std::vector<std::vector<std::string> > >::iterator oit;
		oit = environment.domain_operator_precondition_map.find(normalised_action_name);
		if(oit==environment.domain_operator_precondition_map.end()) {
			std::cerr << "action precondition map entry not found:" << node.dispatch_msg.name << std::endl;
			for (std::map<std::string, std::vector<std::vector<std::string> > >::const_iterator ci = environment.domain_operator_precondition_map.begin(); ci != environment.domain_operator_precondition_map.end(); ++ci)
			{
				std::cerr << (*ci).first;
				const std::vector<std::vector<std::string> >& mapping = (*ci).second;
				for (std::vector<std::vector<std::string> >::const_iterator ci = mapping.begin(); ci != mapping.end(); ++ci)
				{
					const std::vector<std::string>& list = *ci;
					std::cerr << "{";
					for (std::vector<std::string>::const_iterator ci = list.begin(); ci != list.end(); ++ci)
					{
						std::cerr << *ci << ", ";
					}
					std::cerr << "}" << std::endl;
				}
			}
			exit(1);
			return;
		}

		std::vector<rosplan_knowledge_msgs::KnowledgeItem> processed_preconditions;

		// iterate through conditions
		for(std::vector<std::vector<std::string> >::iterator cit = oit->second.begin(); cit!=oit->second.end(); cit++) {

			rosplan_knowledge_msgs::KnowledgeItem condition;
			condition.is_negative = false;

			// set fact or function
			std::map<std::string,std::vector<std::string> >::iterator dit = environment.domain_predicates.find((*cit)[0]);
			if(dit!=environment.domain_predicates.end()) condition.knowledge_type = rosplan_knowledge_msgs::KnowledgeItem::FACT;

			dit = environment.domain_functions.find((*cit)[0]);
			if(dit!=environment.domain_functions.end()) condition.knowledge_type = rosplan_knowledge_msgs::KnowledgeItem::FUNCTION;

			// create edge name
			condition.attribute_name = (*cit)[0];

			std::stringstream ss;
			ss << condition.attribute_name;

			// populate parameters
			int index = 1;

			for(std::vector<std::string>::iterator pit = environment.domain_predicates[condition.attribute_name].begin(); pit!=environment.domain_predicates[condition.attribute_name].end(); pit++) {

				// set parameter label to predicate label
				diagnostic_msgs::KeyValue param;
				param.key = *pit;

				// find label as it is in domain operator
				std::string conditionKey = (*cit)[index];
				std::transform(conditionKey.begin(), conditionKey.end(), conditionKey.begin(), tolower);
				index++;

				// set value
				std::vector<diagnostic_msgs::KeyValue>::iterator opit;
				for(opit = node.dispatch_msg.parameters.begin(); opit!=node.dispatch_msg.parameters.end(); opit++) {

					std::string parameter = opit->key;
					std::transform(parameter.begin(), parameter.end(), parameter.begin(), tolower);

					if(0==parameter.compare(conditionKey)) {
						param.value = opit->value;
						ss << " " << param.value;
					}
				}
				condition.values.push_back(param);
			}

			// Make sure we haven't already processed this precondition.
			bool already_processed = true;
			for (std::vector<rosplan_knowledge_msgs::KnowledgeItem>::const_iterator ci = processed_preconditions.begin(); ci != processed_preconditions.end(); ++ci)
			{
				const rosplan_knowledge_msgs::KnowledgeItem& processed_precondition = *ci;
				if (condition.attribute_name != processed_precondition.attribute_name)
				{
					already_processed = false;
					break;
				}

				for (unsigned int i = 0; i < processed_precondition.values.size(); ++i)
				{
					if (processed_precondition.values[i].value != condition.values[i].value)
					{
						already_processed = false;
						break;
					}
				}
			}

			if (already_processed) continue;

			// create new edge
			StrlEdge* edge = new StrlEdge();
			edge->signal_type = CONDITION;
			edge->edge_name = ss.str();
			edge->active = false;
			edge->sinks.push_back(&node);
			edge->external_conditions.push_back(condition);

			node.input.push_back(edge);
			plan_edges.push_back(edge);
		}
	}

	/*------------*/
	/* Parse plan */
	/*------------*/

	void POPFEsterelPlanParser::createNodeAndEdge(const std::string& action_name, double dispatchTime, double duration, int node_id, PlanningEnvironment &environment, StrlNode& node, StrlEdge& edge) {

		node.node_name = action_name;
		node.node_id = node_id;
		node.dispatched = false;
		node.completed = false;

		// save this parent edge
		edge.signal_type = ACTION;
		std::stringstream ss;
		ss << "e" << node.node_id;
		edge.edge_name = ss.str();
		edge.sources.push_back(&node);
		edge.active = false;
		plan_edges.push_back(&edge);

		// prepare message
		node.output.push_back(&edge);
		node.dispatch_msg.action_id = node.node_id;
		node.dispatch_msg.duration = duration;
		node.dispatch_msg.dispatch_time = dispatchTime;
		node.dispatch_msg.name = action_name;

		// check for parameters
		int curr = 0;
		int next = 0;
		bool paramsExist = (action_name.find(" ",curr) != std::string::npos);
		if(paramsExist) {

			// name
			next = action_name.find(" ",curr);
			node.dispatch_msg.name = action_name.substr(curr,next-curr).c_str();

			// parameters
			int parameter_index = 0;
			std::vector<std::string> params;
			while(next < action_name.length()) {

				curr = next + 1;
				next = action_name.find(" ",curr);
				if(next == std::string::npos)
					next = action_name.length();

				diagnostic_msgs::KeyValue pair;
				pair.key = environment.domain_operators[node.dispatch_msg.name][parameter_index];
				pair.value = action_name.substr(curr,next-curr);
				node.dispatch_msg.parameters.push_back(pair);
				++parameter_index;
			}
		}
		preparePDDLConditions(node, environment);
		plan_nodes.push_back(&node);
		action_list.push_back(node.dispatch_msg);
	}

	/**
	 * Parse a plan written by POPF
	 */
	void POPFEsterelPlanParser::preparePlan(std::string &dataPath, PlanningEnvironment &environment, size_t freeActionID) {

		ROS_INFO("KCL: (POPFEsterelPlanParser) Loading plan from file: %s. Initial action ID: %zu", ((dataPath + "plan.pddl").c_str()), freeActionID);

		// load plan file
		StrlEdge* last_edge = NULL;
		std::ifstream infile((dataPath + "plan.pddl").c_str());
		int curr,next,nodeCount;
		std::string line;
		double expectedPlanDuration = 0;
		bool planFound = false;
		bool planRead = false;

		while(!infile.eof()) {

			std::getline(infile, line);
			toLowerCase(line);

			if (line.substr(0,6).compare("; plan") == 0) {

				// prepare plan
				plan_nodes.clear();
				plan_edges.clear();
				action_list.clear();
				expectedPlanDuration = atof(line.substr(25).c_str());
				planFound = true;
				planRead = false;

				// The last edge that will lead to the next action.
				last_edge = NULL;

			} else if (line.substr(0,6).compare("; time")!=0) {
				//consume useless lines

			} else if (!planRead) {

				nodeCount = freeActionID;
				std::vector<std::string> parentEdge;

				while(!infile.eof() && line.compare("")!=0) {

					std::getline(infile, line);
					toLowerCase(line);

					// 0.000: (goto_waypoint kenny wp0 wp1)  [10.000]
					if (line.length()<2)
						break;

					// dispatchTime
					curr = line.find(":");
					double dispatchTime = (double)atof(line.substr(0,curr).c_str());
					curr += 3;

					// action
					next=line.find(")",curr);
					std::string name = line.substr(curr,next-curr).c_str();

					// duration
					curr=line.find("[",curr)+1;
					next=line.find("]",curr);
					double duration = (double)atof(line.substr(curr,next-curr).c_str());
					{
						StrlNode* node = new StrlNode();
						StrlEdge* edge = new StrlEdge();
						createNodeAndEdge(name, dispatchTime, duration, nodeCount, environment, *node, *edge);
						++nodeCount;

						if (last_edge != NULL)
						{
							node->input.push_back(last_edge);
							last_edge->sinks.push_back(node);
						}
						last_edge = edge;
					}
				}
				planRead = true;
			}
		}

		// printPlan(plan);
		produceEsterel();
		infile.close();
	}

	/*-----------------*/
	/* Produce Esterel */
	/*-----------------*/

	/*
	 * output a plan as an Esterel controller
	 */
	bool POPFEsterelPlanParser::produceEsterel() {

		// output file
		std::string strl_file;
		ros::NodeHandle nh("~");
		nh.param("strl_file_path", strl_file, std::string("common/plan.strl"));

		ROS_INFO("KCL: (POPFEsterelPlanParser) Write the esterel plan: %s", strl_file.c_str());

		std::ofstream dest;
		dest.open(strl_file.c_str());

		// main module
		dest << "module plan:" << std::endl;

		// inputs
		dest << "input SOURCE";
		std::vector<StrlNode*>::iterator nit = plan_nodes.begin();
		for(; nit!=plan_nodes.end(); nit++) {
			dest << ", a" << (*nit)->node_id << "_complete";
		}
		dest << std::endl;

		// outputs
		dest << "output SINK";
		for(nit = plan_nodes.begin(); nit!=plan_nodes.end(); nit++) {
			dest << ", a" << (*nit)->node_id << "_dispatch";
		}
		dest << std::endl;

		// internal signals
		std::vector<StrlEdge*>::iterator eit = plan_edges.begin();
		if(eit!=plan_edges.end()) {
			dest << "signal " << (*eit)->edge_name;
			for(; eit!=plan_edges.end(); eit++) {
				dest << ", " << (*eit)->edge_name;
			}
			dest << " in" << std::endl;
		}

		// run everything
		nit = plan_nodes.begin();
		if(nit!=plan_nodes.end()) {
			dest << "run action" << (*nit)->node_id << std::endl;
			for(; nit!=plan_nodes.end(); nit++) {
				dest << " || action" << (*nit)->node_id << std::endl;
			}
			dest << "end" << std::endl;
		}
		dest << "end module" << std::endl << std::endl;

		// action modules
		nit = plan_nodes.begin();
		for(; nit!=plan_nodes.end(); nit++) {

			dest << "module action" << (*nit)->node_id << ":" << std::endl;

			if((*nit)->input.size() > 0) {
				dest << "input ";
				for(int j=0;j<(*nit)->input.size();j++) {
					if(j>0) dest << ", ";
					dest << (*nit)->input[j]->edge_name;
				}
				dest << ";" << std::endl;
			}

			if((*nit)->output.size() > 0) {
				dest << "output ";
				for(int j=0;j<(*nit)->output.size();j++) {
					if(j>0) dest << ", ";
					dest << (*nit)->output[j]->edge_name;
				}
				dest << ";" << std::endl;
			}

			if((*nit)->input.size() > 0) {
				dest << "  await ";
				for(int j=0;j<(*nit)->input.size();j++) {
					if(j>0) dest << " or ";
					dest << (*nit)->input[j]->edge_name;
				}
				dest << ";" << std::endl;
			}

			dest << "  emit a" << (*nit)->node_id << "_dispatch;" << std::endl;
			dest << "  await a" << (*nit)->node_id << "_complete;" << std::endl;

			for(int j=0;j<(*nit)->output.size();j++) {
				dest << "emit " << (*nit)->output[j]->edge_name;
			}
			dest << ";" << std::endl;
			dest << "end module" << std::endl << std::endl;
		}
		dest.close();
	}
} // close namespace
<|endoftext|>


<commit_before><commit_msg>Testcase for cumipmt<commit_after><|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2011, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 *  Author: Anatoly Baskeheev, Itseez Ltd, (myname.mysurname@mycompany.com)
 */

#ifndef PCL_GPU_DEVICE_ARRAY_
#define PCL_GPU_DEVICE_ARRAY_

#include <vector>
#include "pcl/pcl_macros.h"

namespace pcl
{
    namespace gpu
    {
        ////////////// DeviceArray classes with reference counting /////////////////////

        class PCL_EXPORTS DeviceArray
        {
        public:
            DeviceArray();
            ~DeviceArray();

            DeviceArray(size_t sizeBytes);
            DeviceArray(void *ptr, size_t sizeBytes);

            DeviceArray(const DeviceArray& other);
            DeviceArray& operator=(const DeviceArray& other);

            void create(size_t size);
            void release();

            void upload(const void *host_ptr, size_t sizeBytes);
            void download(void *host_ptr) const;

            template<class T> T* ptr() { return (T*)data_; }
            template<class T> const T* ptr() const { return (const T*)data_; }

            size_t sizeBytes() const;

        private:
            void *data_;
            size_t size_;

            int* refcount_;
        };

        class PCL_EXPORTS DeviceArray2D
        {
        public:
            DeviceArray2D();
            ~DeviceArray2D();

            DeviceArray2D(int rows, int colsBytes);
            DeviceArray2D(int rows, int colsBytes, void *data, size_t stepBytes);

            DeviceArray2D(const DeviceArray2D& other);
            DeviceArray2D& operator=(const DeviceArray2D& other);

            void create(int rows, int colsBytes);
            void release();

            void upload(const void *host_ptr, size_t host_step, int rows, int colsBytes);
            void download(void *host_ptr, size_t host_step) const;

            template<class T> T* ptr(int y = 0) { return (T*)(data_ + y * step_); }
            template<class T> const T* ptr(int y = 0) const { return (const T*)(data_ + y * step_); }

            size_t step() const;
            int colsBytes() const;
            int rows() const;

        private:
            int colsBytes_;
            int rows_;

            char *data_;
            size_t step_;

            int* refcount_;
        };

        ////////////////////// Template versions /////////////////////////////

        template<class T>
        class PCL_EXPORTS DeviceArray_ : private DeviceArray
        {
        public:
            typedef T type;
            enum { elem_size = sizeof(T) };

            DeviceArray_();
            DeviceArray_(size_t size);
            DeviceArray_(T *ptr, size_t size);

            DeviceArray_(const DeviceArray_& other);
            DeviceArray_& operator = (const DeviceArray_& other);

            void create(size_t sizeBytes);
            void release();

            void upload(const T *host_ptr, size_t sizeBytes);
            void download(T *host_ptr) const;

            void upload(const std::vector<T>& data);
            void download(std::vector<T>& data) const;

            T* ptr();
            const T* ptr() const;

            template<class U> U* ptr() { return (U*)ptr(); }
            template<class U> const U* ptr() const { return (const U*)ptr(); }

            operator T*();
            operator const T*() const;

            size_t size() const;
        };

        template<class T>
        class PCL_EXPORTS DeviceArray2D_ : private DeviceArray2D
        {
        public:
            typedef T type;
            enum { elem_size = sizeof(T) };

            DeviceArray2D_();
            DeviceArray2D_(int rows, int cols);
            DeviceArray2D_(int rows, int cols, void *data, size_t stepBytes);

            DeviceArray2D_(const DeviceArray2D_& other);
            DeviceArray2D_& operator = (const DeviceArray2D_& other);

            void create(int rows, int cols);
            void release();

            void upload(const void *host_ptr, size_t host_step, int rows, int cols);
            void download(void *host_ptr, size_t host_step) const;

            void upload(const std::vector<T>& data, int cols);
            void download(std::vector<T>& data, int& cols) const;

            T* ptr(int y = 0);
            const T* ptr(int y = 0) const;

            operator T*();
            operator const T*() const;

            size_t step() const;
            int cols() const;
            int rows() const;
        };

    }
}

/////////////////////  Inline implementations of DeviceArray_ ////////////////////////////////////////////

template<class T> inline pcl::gpu::DeviceArray_<T>::DeviceArray_() {}
template<class T> inline pcl::gpu::DeviceArray_<T>::DeviceArray_(size_t size) : DeviceArray(size * elem_size) {}
template<class T> inline pcl::gpu::DeviceArray_<T>::DeviceArray_(T *ptr, size_t size) : DeviceArray(ptr, size * elem_size) {}
template<class T> inline pcl::gpu::DeviceArray_<T>::DeviceArray_(const DeviceArray_& other) : DeviceArray(other) {}
template<class T> inline pcl::gpu::DeviceArray_<T>& pcl::gpu::DeviceArray_<T>::operator=(const DeviceArray_& other)
{ DeviceArray::operator=(other); return *this; }

template<class T> inline void pcl::gpu::DeviceArray_<T>::create(size_t size) { DeviceArray::create(size * elem_size); }
template<class T> inline void pcl::gpu::DeviceArray_<T>::release()  { DeviceArray::release(); }
template<class T> inline void pcl::gpu::DeviceArray_<T>::upload(const T *host_ptr, size_t size) { DeviceArray::upload(host_ptr, size * elem_size); }
template<class T> inline void pcl::gpu::DeviceArray_<T>::download(T *host_ptr) const { DeviceArray::download( host_ptr ); }
template<class T> inline T* pcl::gpu::DeviceArray_<T>::ptr() { return DeviceArray::ptr<T>(); };
template<class T> inline const T* pcl::gpu::DeviceArray_<T>::ptr() const { return DeviceArray::ptr<T>(); };
template<class T> inline pcl::gpu::DeviceArray_<T>::operator T*() { return ptr(); }
template<class T> inline pcl::gpu::DeviceArray_<T>::operator const T*() const { return ptr(); }
template<class T> inline size_t pcl::gpu::DeviceArray_<T>::size() const { return DeviceArray::sizeBytes() / elem_size; }

template<class T> inline void pcl::gpu::DeviceArray_<T>::upload(const std::vector<T>& data) { upload(&data[0], data.size()); }
template<class T> inline void pcl::gpu::DeviceArray_<T>::download(std::vector<T>& data) const { data.resize(size()); if (!data.empty()) download(&data[0]); }

/////////////////////  Inline implementations of DeviceArray2D_ ////////////////////////////////////////////

template<class T> inline pcl::gpu::DeviceArray2D_<T>::DeviceArray2D_() {}
template<class T> inline pcl::gpu::DeviceArray2D_<T>::DeviceArray2D_(int rows, int cols) : DeviceArray2D(rows, cols * elem_size) {}
template<class T> inline pcl::gpu::DeviceArray2D_<T>::DeviceArray2D_(int rows, int cols, void *data, size_t stepBytes) : DeviceArray2D(rows, cols * elem_size, data, stepBytes) {}
template<class T> inline pcl::gpu::DeviceArray2D_<T>::DeviceArray2D_(const DeviceArray2D_& other) : DeviceArray2D(other) {}
template<class T> inline pcl::gpu::DeviceArray2D_<T>& pcl::gpu::DeviceArray2D_<T>::operator=(const DeviceArray2D_& other)
{ DeviceArray2D::operator=(other); return *this; }

template<class T> inline void pcl::gpu::DeviceArray2D_<T>::create(int rows, int cols) { DeviceArray2D::create(rows, cols * elem_size); }
template<class T> inline void pcl::gpu::DeviceArray2D_<T>::release()  { DeviceArray2D::release(); }

template<class T> inline void pcl::gpu::DeviceArray2D_<T>::upload(const void *host_ptr, size_t host_step, int rows, int cols)
{ DeviceArray2D::upload(host_ptr, host_step, rows, cols * elem_size); }

template<class T> inline void pcl::gpu::DeviceArray2D_<T>::download(void *host_ptr, size_t host_step) const
{ DeviceArray2D::download( host_ptr, host_step ); }

template<class T> inline void pcl::gpu::DeviceArray2D_<T>::upload(const std::vector<T>& data, int cols)
{ upload(&data[0], cols * elem_size, data.size()/cols, cols); }

template<class T> inline void pcl::gpu::DeviceArray2D_<T>::download(std::vector<T>& data, int& elem_step) const
{ elem_step = cols(); data.resize(cols() * rows()); if (!data.empty()) download(&data[0], DeviceArray2D::colsBytes());  }

template<class T> inline T* pcl::gpu::DeviceArray2D_<T>::ptr(int y) { return DeviceArray2D::ptr<T>(y); };
template<class T> inline const T* pcl::gpu::DeviceArray2D_<T>::ptr(int y) const { return DeviceArray2D::ptr<T>(y); };
template<class T> inline pcl::gpu::DeviceArray2D_<T>::operator T*() { return ptr(); }
template<class T> inline pcl::gpu::DeviceArray2D_<T>::operator const T*() const { return ptr(); }

template<class T> inline size_t pcl::gpu::DeviceArray2D_<T>::step() const { return DeviceArray2D::step(); }
template<class T> inline int pcl::gpu::DeviceArray2D_<T>::cols() const { return DeviceArray2D::colsBytes()/elem_size; }
template<class T> inline int pcl::gpu::DeviceArray2D_<T>::rows() const { return DeviceArray2D::rows(); }

#endif /* PCL_GPU_DEVICE_ARRAY_ */<commit_msg>minor (more relevant parameters names in DeviceArray)<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2011, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 *  Author: Anatoly Baskeheev, Itseez Ltd, (myname.mysurname@mycompany.com)
 */

#ifndef PCL_GPU_DEVICE_ARRAY_
#define PCL_GPU_DEVICE_ARRAY_

#include <vector>
#include "pcl/pcl_macros.h"

namespace pcl
{
    namespace gpu
    {
        ////////////// DeviceArray classes with reference counting /////////////////////

        class PCL_EXPORTS DeviceArray
        {
        public:
            DeviceArray();
            ~DeviceArray();

            DeviceArray(size_t sizeBytes);
            DeviceArray(void *ptr, size_t sizeBytes);

            DeviceArray(const DeviceArray& other);
            DeviceArray& operator=(const DeviceArray& other);

            void create(size_t sizeBytes);
            void release();

            void upload(const void *host_ptr, size_t sizeBytes);
            void download(void *host_ptr) const;

            template<class T> T* ptr() { return (T*)data_; }
            template<class T> const T* ptr() const { return (const T*)data_; }

            size_t sizeBytes() const;

        private:
            void *data_;
            size_t size_;

            int* refcount_;
        };

        class PCL_EXPORTS DeviceArray2D
        {
        public:
            DeviceArray2D();
            ~DeviceArray2D();

            DeviceArray2D(int rows, int colsBytes);
            DeviceArray2D(int rows, int colsBytes, void *data, size_t stepBytes);

            DeviceArray2D(const DeviceArray2D& other);
            DeviceArray2D& operator=(const DeviceArray2D& other);

            void create(int rows, int colsBytes);
            void release();

            void upload(const void *host_ptr, size_t host_step, int rows, int colsBytes);
            void download(void *host_ptr, size_t host_step) const;

            template<class T> T* ptr(int y = 0) { return (T*)(data_ + y * step_); }
            template<class T> const T* ptr(int y = 0) const { return (const T*)(data_ + y * step_); }

            size_t step() const;
            int colsBytes() const;
            int rows() const;

        private:
            int colsBytes_;
            int rows_;

            char *data_;
            size_t step_;

            int* refcount_;
        };

        ////////////////////// Template versions /////////////////////////////

        template<class T>
        class PCL_EXPORTS DeviceArray_ : private DeviceArray
        {
        public:
            typedef T type;
            enum { elem_size = sizeof(T) };

            DeviceArray_();
            DeviceArray_(size_t size);
            DeviceArray_(T *ptr, size_t size);

            DeviceArray_(const DeviceArray_& other);
            DeviceArray_& operator = (const DeviceArray_& other);

            void create(size_t size);
            void release();

            void upload(const T *host_ptr, size_t size);
            void download(T *host_ptr) const;

            void upload(const std::vector<T>& data);
            void download(std::vector<T>& data) const;

            T* ptr();
            const T* ptr() const;

            template<class U> U* ptr() { return (U*)ptr(); }
            template<class U> const U* ptr() const { return (const U*)ptr(); }

            operator T*();
            operator const T*() const;

            size_t size() const;
        };

        template<class T>
        class PCL_EXPORTS DeviceArray2D_ : private DeviceArray2D
        {
        public:
            typedef T type;
            enum { elem_size = sizeof(T) };

            DeviceArray2D_();
            DeviceArray2D_(int rows, int cols);
            DeviceArray2D_(int rows, int cols, void *data, size_t stepBytes);

            DeviceArray2D_(const DeviceArray2D_& other);
            DeviceArray2D_& operator = (const DeviceArray2D_& other);

            void create(int rows, int cols);
            void release();

            void upload(const void *host_ptr, size_t host_step, int rows, int cols);
            void download(void *host_ptr, size_t host_step) const;

            void upload(const std::vector<T>& data, int cols);
            void download(std::vector<T>& data, int& cols) const;

            T* ptr(int y = 0);
            const T* ptr(int y = 0) const;

            operator T*();
            operator const T*() const;

            size_t step() const;
            int cols() const;
            int rows() const;
        };

    }
}

/////////////////////  Inline implementations of DeviceArray_ ////////////////////////////////////////////

template<class T> inline pcl::gpu::DeviceArray_<T>::DeviceArray_() {}
template<class T> inline pcl::gpu::DeviceArray_<T>::DeviceArray_(size_t size) : DeviceArray(size * elem_size) {}
template<class T> inline pcl::gpu::DeviceArray_<T>::DeviceArray_(T *ptr, size_t size) : DeviceArray(ptr, size * elem_size) {}
template<class T> inline pcl::gpu::DeviceArray_<T>::DeviceArray_(const DeviceArray_& other) : DeviceArray(other) {}
template<class T> inline pcl::gpu::DeviceArray_<T>& pcl::gpu::DeviceArray_<T>::operator=(const DeviceArray_& other)
{ DeviceArray::operator=(other); return *this; }

template<class T> inline void pcl::gpu::DeviceArray_<T>::create(size_t size) { DeviceArray::create(size * elem_size); }
template<class T> inline void pcl::gpu::DeviceArray_<T>::release()  { DeviceArray::release(); }
template<class T> inline void pcl::gpu::DeviceArray_<T>::upload(const T *host_ptr, size_t size) { DeviceArray::upload(host_ptr, size * elem_size); }
template<class T> inline void pcl::gpu::DeviceArray_<T>::download(T *host_ptr) const { DeviceArray::download( host_ptr ); }
template<class T> inline T* pcl::gpu::DeviceArray_<T>::ptr() { return DeviceArray::ptr<T>(); };
template<class T> inline const T* pcl::gpu::DeviceArray_<T>::ptr() const { return DeviceArray::ptr<T>(); };
template<class T> inline pcl::gpu::DeviceArray_<T>::operator T*() { return ptr(); }
template<class T> inline pcl::gpu::DeviceArray_<T>::operator const T*() const { return ptr(); }
template<class T> inline size_t pcl::gpu::DeviceArray_<T>::size() const { return DeviceArray::sizeBytes() / elem_size; }

template<class T> inline void pcl::gpu::DeviceArray_<T>::upload(const std::vector<T>& data) { upload(&data[0], data.size()); }
template<class T> inline void pcl::gpu::DeviceArray_<T>::download(std::vector<T>& data) const { data.resize(size()); if (!data.empty()) download(&data[0]); }

/////////////////////  Inline implementations of DeviceArray2D_ ////////////////////////////////////////////

template<class T> inline pcl::gpu::DeviceArray2D_<T>::DeviceArray2D_() {}
template<class T> inline pcl::gpu::DeviceArray2D_<T>::DeviceArray2D_(int rows, int cols) : DeviceArray2D(rows, cols * elem_size) {}
template<class T> inline pcl::gpu::DeviceArray2D_<T>::DeviceArray2D_(int rows, int cols, void *data, size_t stepBytes) : DeviceArray2D(rows, cols * elem_size, data, stepBytes) {}
template<class T> inline pcl::gpu::DeviceArray2D_<T>::DeviceArray2D_(const DeviceArray2D_& other) : DeviceArray2D(other) {}
template<class T> inline pcl::gpu::DeviceArray2D_<T>& pcl::gpu::DeviceArray2D_<T>::operator=(const DeviceArray2D_& other)
{ DeviceArray2D::operator=(other); return *this; }

template<class T> inline void pcl::gpu::DeviceArray2D_<T>::create(int rows, int cols) { DeviceArray2D::create(rows, cols * elem_size); }
template<class T> inline void pcl::gpu::DeviceArray2D_<T>::release()  { DeviceArray2D::release(); }

template<class T> inline void pcl::gpu::DeviceArray2D_<T>::upload(const void *host_ptr, size_t host_step, int rows, int cols)
{ DeviceArray2D::upload(host_ptr, host_step, rows, cols * elem_size); }

template<class T> inline void pcl::gpu::DeviceArray2D_<T>::download(void *host_ptr, size_t host_step) const
{ DeviceArray2D::download( host_ptr, host_step ); }

template<class T> inline void pcl::gpu::DeviceArray2D_<T>::upload(const std::vector<T>& data, int cols)
{ upload(&data[0], cols * elem_size, data.size()/cols, cols); }

template<class T> inline void pcl::gpu::DeviceArray2D_<T>::download(std::vector<T>& data, int& elem_step) const
{ elem_step = cols(); data.resize(cols() * rows()); if (!data.empty()) download(&data[0], DeviceArray2D::colsBytes());  }

template<class T> inline T* pcl::gpu::DeviceArray2D_<T>::ptr(int y) { return DeviceArray2D::ptr<T>(y); };
template<class T> inline const T* pcl::gpu::DeviceArray2D_<T>::ptr(int y) const { return DeviceArray2D::ptr<T>(y); };
template<class T> inline pcl::gpu::DeviceArray2D_<T>::operator T*() { return ptr(); }
template<class T> inline pcl::gpu::DeviceArray2D_<T>::operator const T*() const { return ptr(); }

template<class T> inline size_t pcl::gpu::DeviceArray2D_<T>::step() const { return DeviceArray2D::step(); }
template<class T> inline int pcl::gpu::DeviceArray2D_<T>::cols() const { return DeviceArray2D::colsBytes()/elem_size; }
template<class T> inline int pcl::gpu::DeviceArray2D_<T>::rows() const { return DeviceArray2D::rows(); }

#endif /* PCL_GPU_DEVICE_ARRAY_ */<|endoftext|>