<commit_before>/*
 * Copyright (C) 2014 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <iostream>
#include <iterator>
#include <regex>

#include "cql3_type.hh"
#include "cql3/util.hh"
#include "ut_name.hh"
#include "database.hh"
#include "user_types_metadata.hh"
#include "types/map.hh"
#include "types/set.hh"
#include "types/list.hh"

namespace cql3 {

cql3_type cql3_type::raw::prepare(database& db, const sstring& keyspace) {
    try {
        auto&& ks = db.find_keyspace(keyspace);
        return prepare_internal(keyspace, *ks.metadata()->user_types());
    } catch (no_such_keyspace& nsk) {
        throw exceptions::invalid_request_exception("Unknown keyspace " + keyspace);
    }
}

bool cql3_type::raw::is_duration() const {
    return false;
}

bool cql3_type::raw::references_user_type(const sstring& name) const {
    return false;
}

class cql3_type::raw_type : public raw {
private:
    cql3_type _type;

    virtual sstring to_string() const override {
        return _type.to_string();
    }
public:
    raw_type(cql3_type type)
        : _type{type}
    { }
public:
    virtual cql3_type prepare(database& db, const sstring& keyspace) {
        return _type;
    }
    cql3_type prepare_internal(const sstring&, user_types_metadata&) override {
        return _type;
    }

    virtual bool supports_freezing() const {
        return false;
    }

    virtual bool is_counter() const {
        return _type.is_counter();
    }

    virtual bool is_duration() const override {
        return _type.get_type() == duration_type;
    }
};

class cql3_type::raw_collection : public raw {
    const abstract_type::kind _kind;
    shared_ptr<raw> _keys;
    shared_ptr<raw> _values;

    virtual sstring to_string() const override {
        sstring start = is_frozen() ? "frozen<" : "";
        sstring end = is_frozen() ? ">" : "";
        if (_kind == abstract_type::kind::list) {
            return format("{}list<{}>{}", start, _values, end);
        } else if (_kind == abstract_type::kind::set) {
            return format("{}set<{}>{}", start, _values, end);
        } else if (_kind == abstract_type::kind::map) {
            return format("{}map<{}, {}>{}", start, _keys, _values, end);
        }
        abort();
    }
public:
    raw_collection(const abstract_type::kind kind, shared_ptr<raw> keys, shared_ptr<raw> values)
            : _kind(kind), _keys(std::move(keys)), _values(std::move(values)) {
    }

    virtual void freeze() override {
        if (_keys && _keys->supports_freezing()) {
            _keys->freeze();
        }
        if (_values && _values->supports_freezing()) {
            _values->freeze();
        }
        _frozen = true;
    }

    virtual bool supports_freezing() const override {
        return true;
    }

    virtual bool is_collection() const override {
        return true;
    }

    virtual cql3_type prepare_internal(const sstring& keyspace, user_types_metadata& user_types) override {
        assert(_values); // "Got null values type for a collection";

        if (!is_frozen() && _values->supports_freezing() && !_values->is_frozen()) {
            throw exceptions::invalid_request_exception(
                    format("Non-frozen user types or collections are not allowed inside collections: {}", *this));
        }
        if (_values->is_counter()) {
            throw exceptions::invalid_request_exception(format("Counters are not allowed inside collections: {}", *this));
        }

        if (_keys) {
            if (!is_frozen() && _keys->supports_freezing() && !_keys->is_frozen()) {
                throw exceptions::invalid_request_exception(
                        format("Non-frozen user types or collections are not allowed inside collections: {}", *this));
            }
        }

        if (_kind == abstract_type::kind::list) {
            return cql3_type(list_type_impl::get_instance(_values->prepare_internal(keyspace, user_types).get_type(), !is_frozen()));
        } else if (_kind == abstract_type::kind::set) {
            if (_values->is_duration()) {
                throw exceptions::invalid_request_exception(format("Durations are not allowed inside sets: {}", *this));
            }
            return cql3_type(set_type_impl::get_instance(_values->prepare_internal(keyspace, user_types).get_type(), !is_frozen()));
        } else if (_kind == abstract_type::kind::map) {
            assert(_keys); // "Got null keys type for a collection";
            if (_keys->is_duration()) {
                throw exceptions::invalid_request_exception(format("Durations are not allowed as map keys: {}", *this));
            }
            return cql3_type(map_type_impl::get_instance(_keys->prepare_internal(keyspace, user_types).get_type(), _values->prepare_internal(keyspace, user_types).get_type(), !is_frozen()));
        }
        abort();
    }

    bool references_user_type(const sstring& name) const override {
        return (_keys && _keys->references_user_type(name)) || _values->references_user_type(name);
    }

    bool is_duration() const override {
        return false;
    }
};

class cql3_type::raw_ut : public raw {
    ut_name _name;

    virtual sstring to_string() const override {
        return _name.to_string();
    }
public:
    raw_ut(ut_name name)
            : _name(std::move(name)) {
    }

    virtual std::optional<sstring> keyspace() const override {
        return _name.get_keyspace();
    }

    virtual void freeze() override {
        _frozen = true;
    }

    virtual cql3_type prepare_internal(const sstring& keyspace, user_types_metadata& user_types) override {
        if (_name.has_keyspace()) {
            // The provided keyspace is the one of the current statement this is part of. If it's different from the keyspace of
            // the UTName, we reject since we want to limit user types to their own keyspace (see #6643)
            if (!keyspace.empty() && keyspace != _name.get_keyspace()) {
                throw exceptions::invalid_request_exception(sprint("Statement on keyspace %s cannot refer to a user type in keyspace %s; "
                                                                   "user types can only be used in the keyspace they are defined in",
                                                                keyspace, _name.get_keyspace()));
            }
        } else {
            _name.set_keyspace(keyspace);
        }
        try {
            auto&& type = user_types.get_type(_name.get_user_type_name());
            if (!is_frozen()) {
                throw exceptions::invalid_request_exception("Non-frozen User-Defined types are not supported, please use frozen<>");
            }
            return cql3_type(std::move(type));
        } catch (std::out_of_range& e) {
            throw exceptions::invalid_request_exception(format("Unknown type {}", _name));
        }
    }
    bool references_user_type(const sstring& name) const override {
        return _name.get_string_type_name() == name;
    }
    virtual bool supports_freezing() const override {
        return true;
    }

    virtual bool is_user_type() const override {
        return true;
    }
};

class cql3_type::raw_tuple : public raw {
    std::vector<shared_ptr<raw>> _types;

    virtual sstring to_string() const override {
        return format("tuple<{}>", join(", ", _types));
    }
public:
    raw_tuple(std::vector<shared_ptr<raw>> types)
            : _types(std::move(types)) {
    }
    virtual bool supports_freezing() const override {
        return true;
    }
    virtual bool is_collection() const override {
        return false;
    }
    virtual void freeze() override {
        for (auto&& t : _types) {
            if (t->supports_freezing()) {
                t->freeze();
            }
        }
        _frozen = true;
    }
    virtual cql3_type prepare_internal(const sstring& keyspace, user_types_metadata& user_types) override {
        if (!is_frozen()) {
            freeze();
        }
        std::vector<data_type> ts;
        for (auto&& t : _types) {
            if (t->is_counter()) {
                throw exceptions::invalid_request_exception("Counters are not allowed inside tuples");
            }
            ts.push_back(t->prepare_internal(keyspace, user_types).get_type());
        }
        return tuple_type_impl::get_instance(std::move(ts))->as_cql3_type();
    }

    bool references_user_type(const sstring& name) const override {
        return std::any_of(_types.begin(), _types.end(), [&name](auto t) {
            return t->references_user_type(name);
        });
    }
};

bool
cql3_type::raw::is_collection() const {
    return false;
}

bool
cql3_type::raw::is_counter() const {
    return false;
}

bool
cql3_type::raw::is_user_type() const {
    return false;
}

bool
cql3_type::raw::is_frozen() const {
    return _frozen;
}

std::optional<sstring>
cql3_type::raw::keyspace() const {
    return std::nullopt;
}

void
cql3_type::raw::freeze() {
    sstring message = format("frozen<> is only allowed on collections, tuples, and user-defined types (got {})", to_string());
    throw exceptions::invalid_request_exception(message);
}

shared_ptr<cql3_type::raw>
cql3_type::raw::from(cql3_type type) {
    return ::make_shared<raw_type>(type);
}

shared_ptr<cql3_type::raw>
cql3_type::raw::user_type(ut_name name) {
    return ::make_shared<raw_ut>(name);
}

shared_ptr<cql3_type::raw>
cql3_type::raw::map(shared_ptr<raw> t1, shared_ptr<raw> t2) {
    return make_shared(raw_collection(abstract_type::kind::map, std::move(t1), std::move(t2)));
}

shared_ptr<cql3_type::raw>
cql3_type::raw::list(shared_ptr<raw> t) {
    return make_shared(raw_collection(abstract_type::kind::list, {}, std::move(t)));
}

shared_ptr<cql3_type::raw>
cql3_type::raw::set(shared_ptr<raw> t) {
    return make_shared(raw_collection(abstract_type::kind::set, {}, std::move(t)));
}

shared_ptr<cql3_type::raw>
cql3_type::raw::tuple(std::vector<shared_ptr<raw>> ts) {
    return make_shared(raw_tuple(std::move(ts)));
}

shared_ptr<cql3_type::raw>
cql3_type::raw::frozen(shared_ptr<raw> t) {
    t->freeze();
    return t;
}

thread_local cql3_type cql3_type::ascii{ascii_type};
thread_local cql3_type cql3_type::bigint{long_type};
thread_local cql3_type cql3_type::blob{bytes_type};
thread_local cql3_type cql3_type::boolean{boolean_type};
thread_local cql3_type cql3_type::double_{double_type};
thread_local cql3_type cql3_type::empty{empty_type};
thread_local cql3_type cql3_type::float_{float_type};
thread_local cql3_type cql3_type::int_{int32_type};
thread_local cql3_type cql3_type::smallint{short_type};
thread_local cql3_type cql3_type::text{utf8_type};
thread_local cql3_type cql3_type::timestamp{timestamp_type};
thread_local cql3_type cql3_type::tinyint{byte_type};
thread_local cql3_type cql3_type::uuid{uuid_type};
thread_local cql3_type cql3_type::timeuuid{timeuuid_type};
thread_local cql3_type cql3_type::date{simple_date_type};
thread_local cql3_type cql3_type::time{time_type};
thread_local cql3_type cql3_type::inet{inet_addr_type};
thread_local cql3_type cql3_type::varint{varint_type};
thread_local cql3_type cql3_type::decimal{decimal_type};
thread_local cql3_type cql3_type::counter{counter_type};
thread_local cql3_type cql3_type::duration{duration_type};

const std::vector<cql3_type>&
cql3_type::values() {
    static thread_local std::vector<cql3_type> v = {
        cql3_type::ascii,
        cql3_type::bigint,
        cql3_type::blob,
        cql3_type::boolean,
        cql3_type::counter,
        cql3_type::decimal,
        cql3_type::double_,
        cql3_type::empty,
        cql3_type::float_,
        cql3_type::inet,
        cql3_type::int_,
        cql3_type::smallint,
        cql3_type::text,
        cql3_type::timestamp,
        cql3_type::tinyint,
        cql3_type::uuid,
        cql3_type::varint,
        cql3_type::timeuuid,
        cql3_type::date,
        cql3_type::time,
        cql3_type::duration,
    };
    return v;
}

std::ostream&
operator<<(std::ostream& os, const cql3_type::raw& r) {
    return os << r.to_string();
}

namespace util {

sstring maybe_quote(const sstring& identifier) {
    static const std::regex unquoted_identifier_re("[a-z][a-z0-9_]*");
    if (std::regex_match(identifier.begin(), identifier.end(), unquoted_identifier_re)) {
        return identifier;
    }
    static const std::regex double_quote_re("\"");
    std::string result = identifier;
    std::regex_replace(result, double_quote_re, "\"\"");
    return '"' + result + '"';
}

}

}

<commit_msg>cql3: make cql3_type::raw_ut::to_string distinguish frozenness.<commit_after>/*
 * Copyright (C) 2014 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <iostream>
#include <iterator>
#include <regex>

#include "cql3_type.hh"
#include "cql3/util.hh"
#include "ut_name.hh"
#include "database.hh"
#include "user_types_metadata.hh"
#include "types/map.hh"
#include "types/set.hh"
#include "types/list.hh"

namespace cql3 {

cql3_type cql3_type::raw::prepare(database& db, const sstring& keyspace) {
    try {
        auto&& ks = db.find_keyspace(keyspace);
        return prepare_internal(keyspace, *ks.metadata()->user_types());
    } catch (no_such_keyspace& nsk) {
        throw exceptions::invalid_request_exception("Unknown keyspace " + keyspace);
    }
}

bool cql3_type::raw::is_duration() const {
    return false;
}

bool cql3_type::raw::references_user_type(const sstring& name) const {
    return false;
}

class cql3_type::raw_type : public raw {
private:
    cql3_type _type;

    virtual sstring to_string() const override {
        return _type.to_string();
    }
public:
    raw_type(cql3_type type)
        : _type{type}
    { }
public:
    virtual cql3_type prepare(database& db, const sstring& keyspace) {
        return _type;
    }
    cql3_type prepare_internal(const sstring&, user_types_metadata&) override {
        return _type;
    }

    virtual bool supports_freezing() const {
        return false;
    }

    virtual bool is_counter() const {
        return _type.is_counter();
    }

    virtual bool is_duration() const override {
        return _type.get_type() == duration_type;
    }
};

class cql3_type::raw_collection : public raw {
    const abstract_type::kind _kind;
    shared_ptr<raw> _keys;
    shared_ptr<raw> _values;

    virtual sstring to_string() const override {
        sstring start = is_frozen() ? "frozen<" : "";
        sstring end = is_frozen() ? ">" : "";
        if (_kind == abstract_type::kind::list) {
            return format("{}list<{}>{}", start, _values, end);
        } else if (_kind == abstract_type::kind::set) {
            return format("{}set<{}>{}", start, _values, end);
        } else if (_kind == abstract_type::kind::map) {
            return format("{}map<{}, {}>{}", start, _keys, _values, end);
        }
        abort();
    }
public:
    raw_collection(const abstract_type::kind kind, shared_ptr<raw> keys, shared_ptr<raw> values)
            : _kind(kind), _keys(std::move(keys)), _values(std::move(values)) {
    }

    virtual void freeze() override {
        if (_keys && _keys->supports_freezing()) {
            _keys->freeze();
        }
        if (_values && _values->supports_freezing()) {
            _values->freeze();
        }
        _frozen = true;
    }

    virtual bool supports_freezing() const override {
        return true;
    }

    virtual bool is_collection() const override {
        return true;
    }

    virtual cql3_type prepare_internal(const sstring& keyspace, user_types_metadata& user_types) override {
        assert(_values); // "Got null values type for a collection";

        if (!is_frozen() && _values->supports_freezing() && !_values->is_frozen()) {
            throw exceptions::invalid_request_exception(
                    format("Non-frozen user types or collections are not allowed inside collections: {}", *this));
        }
        if (_values->is_counter()) {
            throw exceptions::invalid_request_exception(format("Counters are not allowed inside collections: {}", *this));
        }

        if (_keys) {
            if (!is_frozen() && _keys->supports_freezing() && !_keys->is_frozen()) {
                throw exceptions::invalid_request_exception(
                        format("Non-frozen user types or collections are not allowed inside collections: {}", *this));
            }
        }

        if (_kind == abstract_type::kind::list) {
            return cql3_type(list_type_impl::get_instance(_values->prepare_internal(keyspace, user_types).get_type(), !is_frozen()));
        } else if (_kind == abstract_type::kind::set) {
            if (_values->is_duration()) {
                throw exceptions::invalid_request_exception(format("Durations are not allowed inside sets: {}", *this));
            }
            return cql3_type(set_type_impl::get_instance(_values->prepare_internal(keyspace, user_types).get_type(), !is_frozen()));
        } else if (_kind == abstract_type::kind::map) {
            assert(_keys); // "Got null keys type for a collection";
            if (_keys->is_duration()) {
                throw exceptions::invalid_request_exception(format("Durations are not allowed as map keys: {}", *this));
            }
            return cql3_type(map_type_impl::get_instance(_keys->prepare_internal(keyspace, user_types).get_type(), _values->prepare_internal(keyspace, user_types).get_type(), !is_frozen()));
        }
        abort();
    }

    bool references_user_type(const sstring& name) const override {
        return (_keys && _keys->references_user_type(name)) || _values->references_user_type(name);
    }

    bool is_duration() const override {
        return false;
    }
};

class cql3_type::raw_ut : public raw {
    ut_name _name;

    virtual sstring to_string() const override {
        if (is_frozen()) {
            return format("frozen<{}>", _name.to_string());
        }

        return _name.to_string();
    }
public:
    raw_ut(ut_name name)
            : _name(std::move(name)) {
    }

    virtual std::optional<sstring> keyspace() const override {
        return _name.get_keyspace();
    }

    virtual void freeze() override {
        _frozen = true;
    }

    virtual cql3_type prepare_internal(const sstring& keyspace, user_types_metadata& user_types) override {
        if (_name.has_keyspace()) {
            // The provided keyspace is the one of the current statement this is part of. If it's different from the keyspace of
            // the UTName, we reject since we want to limit user types to their own keyspace (see #6643)
            if (!keyspace.empty() && keyspace != _name.get_keyspace()) {
                throw exceptions::invalid_request_exception(sprint("Statement on keyspace %s cannot refer to a user type in keyspace %s; "
                                                                   "user types can only be used in the keyspace they are defined in",
                                                                keyspace, _name.get_keyspace()));
            }
        } else {
            _name.set_keyspace(keyspace);
        }
        try {
            auto&& type = user_types.get_type(_name.get_user_type_name());
            if (!is_frozen()) {
                throw exceptions::invalid_request_exception("Non-frozen User-Defined types are not supported, please use frozen<>");
            }
            return cql3_type(std::move(type));
        } catch (std::out_of_range& e) {
            throw exceptions::invalid_request_exception(format("Unknown type {}", _name));
        }
    }
    bool references_user_type(const sstring& name) const override {
        return _name.get_string_type_name() == name;
    }
    virtual bool supports_freezing() const override {
        return true;
    }

    virtual bool is_user_type() const override {
        return true;
    }
};

class cql3_type::raw_tuple : public raw {
    std::vector<shared_ptr<raw>> _types;

    virtual sstring to_string() const override {
        return format("tuple<{}>", join(", ", _types));
    }
public:
    raw_tuple(std::vector<shared_ptr<raw>> types)
            : _types(std::move(types)) {
    }
    virtual bool supports_freezing() const override {
        return true;
    }
    virtual bool is_collection() const override {
        return false;
    }
    virtual void freeze() override {
        for (auto&& t : _types) {
            if (t->supports_freezing()) {
                t->freeze();
            }
        }
        _frozen = true;
    }
    virtual cql3_type prepare_internal(const sstring& keyspace, user_types_metadata& user_types) override {
        if (!is_frozen()) {
            freeze();
        }
        std::vector<data_type> ts;
        for (auto&& t : _types) {
            if (t->is_counter()) {
                throw exceptions::invalid_request_exception("Counters are not allowed inside tuples");
            }
            ts.push_back(t->prepare_internal(keyspace, user_types).get_type());
        }
        return tuple_type_impl::get_instance(std::move(ts))->as_cql3_type();
    }

    bool references_user_type(const sstring& name) const override {
        return std::any_of(_types.begin(), _types.end(), [&name](auto t) {
            return t->references_user_type(name);
        });
    }
};

bool
cql3_type::raw::is_collection() const {
    return false;
}

bool
cql3_type::raw::is_counter() const {
    return false;
}

bool
cql3_type::raw::is_user_type() const {
    return false;
}

bool
cql3_type::raw::is_frozen() const {
    return _frozen;
}

std::optional<sstring>
cql3_type::raw::keyspace() const {
    return std::nullopt;
}

void
cql3_type::raw::freeze() {
    sstring message = format("frozen<> is only allowed on collections, tuples, and user-defined types (got {})", to_string());
    throw exceptions::invalid_request_exception(message);
}

shared_ptr<cql3_type::raw>
cql3_type::raw::from(cql3_type type) {
    return ::make_shared<raw_type>(type);
}

shared_ptr<cql3_type::raw>
cql3_type::raw::user_type(ut_name name) {
    return ::make_shared<raw_ut>(name);
}

shared_ptr<cql3_type::raw>
cql3_type::raw::map(shared_ptr<raw> t1, shared_ptr<raw> t2) {
    return make_shared(raw_collection(abstract_type::kind::map, std::move(t1), std::move(t2)));
}

shared_ptr<cql3_type::raw>
cql3_type::raw::list(shared_ptr<raw> t) {
    return make_shared(raw_collection(abstract_type::kind::list, {}, std::move(t)));
}

shared_ptr<cql3_type::raw>
cql3_type::raw::set(shared_ptr<raw> t) {
    return make_shared(raw_collection(abstract_type::kind::set, {}, std::move(t)));
}

shared_ptr<cql3_type::raw>
cql3_type::raw::tuple(std::vector<shared_ptr<raw>> ts) {
    return make_shared(raw_tuple(std::move(ts)));
}

shared_ptr<cql3_type::raw>
cql3_type::raw::frozen(shared_ptr<raw> t) {
    t->freeze();
    return t;
}

thread_local cql3_type cql3_type::ascii{ascii_type};
thread_local cql3_type cql3_type::bigint{long_type};
thread_local cql3_type cql3_type::blob{bytes_type};
thread_local cql3_type cql3_type::boolean{boolean_type};
thread_local cql3_type cql3_type::double_{double_type};
thread_local cql3_type cql3_type::empty{empty_type};
thread_local cql3_type cql3_type::float_{float_type};
thread_local cql3_type cql3_type::int_{int32_type};
thread_local cql3_type cql3_type::smallint{short_type};
thread_local cql3_type cql3_type::text{utf8_type};
thread_local cql3_type cql3_type::timestamp{timestamp_type};
thread_local cql3_type cql3_type::tinyint{byte_type};
thread_local cql3_type cql3_type::uuid{uuid_type};
thread_local cql3_type cql3_type::timeuuid{timeuuid_type};
thread_local cql3_type cql3_type::date{simple_date_type};
thread_local cql3_type cql3_type::time{time_type};
thread_local cql3_type cql3_type::inet{inet_addr_type};
thread_local cql3_type cql3_type::varint{varint_type};
thread_local cql3_type cql3_type::decimal{decimal_type};
thread_local cql3_type cql3_type::counter{counter_type};
thread_local cql3_type cql3_type::duration{duration_type};

const std::vector<cql3_type>&
cql3_type::values() {
    static thread_local std::vector<cql3_type> v = {
        cql3_type::ascii,
        cql3_type::bigint,
        cql3_type::blob,
        cql3_type::boolean,
        cql3_type::counter,
        cql3_type::decimal,
        cql3_type::double_,
        cql3_type::empty,
        cql3_type::float_,
        cql3_type::inet,
        cql3_type::int_,
        cql3_type::smallint,
        cql3_type::text,
        cql3_type::timestamp,
        cql3_type::tinyint,
        cql3_type::uuid,
        cql3_type::varint,
        cql3_type::timeuuid,
        cql3_type::date,
        cql3_type::time,
        cql3_type::duration,
    };
    return v;
}

std::ostream&
operator<<(std::ostream& os, const cql3_type::raw& r) {
    return os << r.to_string();
}

namespace util {

sstring maybe_quote(const sstring& identifier) {
    static const std::regex unquoted_identifier_re("[a-z][a-z0-9_]*");
    if (std::regex_match(identifier.begin(), identifier.end(), unquoted_identifier_re)) {
        return identifier;
    }
    static const std::regex double_quote_re("\"");
    std::string result = identifier;
    std::regex_replace(result, double_quote_re, "\"\"");
    return '"' + result + '"';
}

}

}

<|endoftext|>


<commit_before>/**
 * Copyright 2007-2019 IMP Inventors. All rights reserved.
 */

#include <exception>
#include <iostream>
#include <string>

#include "RMF/FileConstHandle.h"
#include "RMF/FileHandle.h"
#include "RMF/ID.h"
#include "RMF/infrastructure_macros.h"
#include "RMF/utility.h"
#include "common.h"

namespace {
std::string description("Grab frames from an rmf file");
}

int main(int argc, char** argv) {
  try {
    RMF_ADD_INPUT_FILE("input_rmf");
    RMF_ADD_OUTPUT_FILE("output_rmf");
    RMF_ADD_FRAMES;
    process_options(argc, argv);

    RMF::FileConstHandle rh = RMF::open_rmf_file_read_only(input);
    RMF::FileHandle orh = RMF::create_rmf_file(output);
    RMF::clone_file_info(rh, orh);
    orh.set_producer("rmf_slice");
    RMF::clone_hierarchy(rh, orh);
    RMF::clone_static_frame(rh, orh);
    std::cout << "Copying frames";
    unsigned num_copied = 0;
    RMF_FOREACH(RMF::FrameID f, rh.get_frames()) {
      if (f.get_index() < static_cast<unsigned int>(start_frame)) continue;
      if ((f.get_index() - start_frame) % step_frame != 0) continue;
      rh.set_current_frame(f);
      orh.add_frame(rh.get_name(f), rh.get_type(f));
      RMF::clone_loaded_frame(rh, orh);
      num_copied++;
      if (orh.get_number_of_frames() % 10 == 0) std::cout << "." << std::flush;
    }
    std::cout << std::endl;
    std::cout << num_copied << " frames copied" << std::endl;
    return 0;
  }
  catch (const std::exception& e) {
    std::cerr << "Error: " << e.what() << std::endl;
    return 1;
  }
}
<commit_msg>Allow suppression of rmf_slice std output<commit_after>/**
 * Copyright 2007-2019 IMP Inventors. All rights reserved.
 */

#include <exception>
#include <iostream>
#include <string>

#include "RMF/FileConstHandle.h"
#include "RMF/FileHandle.h"
#include "RMF/ID.h"
#include "RMF/infrastructure_macros.h"
#include "RMF/utility.h"
#include "common.h"

namespace {
std::string description("Grab frames from an rmf file");
}

int main(int argc, char** argv) {
  try {
    RMF_ADD_INPUT_FILE("input_rmf");
    RMF_ADD_OUTPUT_FILE("output_rmf");
    RMF_ADD_FRAMES;
    bool silent=false;
    options.add_options()("invisible,v",
                          boost::program_options::bool_switch(&silent),
                          "Suppress all non-error output");
    process_options(argc, argv);

    RMF::FileConstHandle rh = RMF::open_rmf_file_read_only(input);
    RMF::FileHandle orh = RMF::create_rmf_file(output);
    RMF::clone_file_info(rh, orh);
    orh.set_producer("rmf_slice");
    RMF::clone_hierarchy(rh, orh);
    RMF::clone_static_frame(rh, orh);
    if(!silent) std::cout << "Copying frames";
    unsigned num_copied = 0;
    RMF_FOREACH(RMF::FrameID f, rh.get_frames()) {
      if (f.get_index() < static_cast<unsigned int>(start_frame)) continue;
      if ((f.get_index() - start_frame) % step_frame != 0) continue;
      rh.set_current_frame(f);
      orh.add_frame(rh.get_name(f), rh.get_type(f));
      RMF::clone_loaded_frame(rh, orh);
      num_copied++;
      if (orh.get_number_of_frames() % 10 == 0) std::cout << "." << std::flush;
    }
    if(!silent) std::cout << std::endl;
    if(!silent) std::cout << num_copied << " frames copied" << std::endl;
    return 0;
  }
  catch (const std::exception& e) {
    std::cerr << "Error: " << e.what() << std::endl;
    return 1;
  }
}
<|endoftext|>


<commit_before>#include "realm.h"
#include "realm/cmdline.h"

#include <cstdio>
#include <cstdlib>
#include <cassert>

using namespace Realm;

enum {
  TOP_LEVEL_TASK = Processor::TASK_ID_FIRST_AVAILABLE+0,
};

// The goal of this test is to confirm that several different Realm
// synchronization promitives are sufficient to act as synchronization
// primitives under the C++ memory model. The most valuable version of
// this test will be run with thread-sanitizer to confirm these relationships

int x, y;

struct SyncPrimitives {
  UserEvent test_wait;
  UserEvent test_triggered;
  Barrier test_bar;
};

void top_level_task(const void *args, size_t arglen,
		    const void *userdata, size_t userlen, Processor p)
{
  const SyncPrimitives *primitives = (const SyncPrimitives*)args;
  assert(x == 11);
  x = 42;
  primitives->test_wait.trigger();
  primitives->test_triggered.subscribe();
  while (!primitives->test_triggered.has_triggered()) { }
  assert(x == 1729);
  x = 6174;
  primitives->test_bar.arrive();
  primitives->test_bar.wait();
  assert(y == 23);
  y = 2520;
}

int main(int argc, char **argv)
{
  Runtime rt;

  rt.init(&argc, &argv);

  rt.register_task(TOP_LEVEL_TASK, top_level_task);

  // select a processor to run the top level task on
  Processor p = Machine::ProcessorQuery(Machine::get_machine())
    .only_kind(Processor::LOC_PROC)
    .first();
  assert(p.exists());

  SyncPrimitives primitives;
  primitives.test_wait = UserEvent::create_user_event();
  primitives.test_triggered = UserEvent::create_user_event();
  primitives.test_bar = Barrier::create_barrier(2);

  x = 11;
  // Collective launch a single task on each CPU processor of each node, that
  // just means this test will be done once on each node
  Event e = rt.collective_spawn_by_kind(Processor::LOC_PROC, TOP_LEVEL_TASK,
                      &primitives, sizeof(primitives), true/*one per node*/);
  // request shutdown once that task is complete
  rt.shutdown(e);

  primitives.test_wait.external_wait();
  assert(x == 42);
  x = 1729;
  primitives.test_triggered.trigger();
  y = 23;
  primitives.test_bar.arrive();
  primitives.test_bar.wait();
  assert(x == 6174);

  // now sleep this thread until that shutdown actually happens
  rt.wait_for_shutdown();
  assert(y == 2520);

  return 0;
}

<commit_msg>test: clean up memmodel test<commit_after>#include "realm.h"
#include "realm/cmdline.h"

#include <cstdio>
#include <cstdlib>
#include <cassert>

using namespace Realm;

enum {
  TOP_LEVEL_TASK = Processor::TASK_ID_FIRST_AVAILABLE+0,
};

// The goal of this test is to confirm that several different Realm
// synchronization promitives are sufficient to act as synchronization
// primitives under the C++ memory model. The most valuable version of
// this test will be run with thread-sanitizer to confirm these relationships

int x, y;

struct SyncPrimitives {
  UserEvent test_wait;
  UserEvent test_triggered;
  Barrier test_bar;
};

void top_level_task(const void *args, size_t arglen,
		    const void *userdata, size_t userlen, Processor p)
{
  const SyncPrimitives *primitives = (const SyncPrimitives*)args;
  // Make sure that task launching synchronizes
  assert(x == 11);
  // Make sure that user-event triggers synchronzie with waits
  x = 42;
  primitives->test_wait.trigger();
  // Make sure that user-event triggers synchronize with has_triggered
  primitives->test_triggered.subscribe();
  while (!primitives->test_triggered.has_triggered()) { }
  assert(x == 1729);
  // Make sure that barrier arrive and wait synchronize
  x = 6174;
  primitives->test_bar.arrive();
  primitives->test_bar.wait();
  assert(y == 23);
  // Make sure that task completion events synchronize
  y = 2520;
}

int main(int argc, char **argv)
{
  Runtime rt;

  rt.init(&argc, &argv);

  rt.register_task(TOP_LEVEL_TASK, top_level_task);

  SyncPrimitives primitives;
  primitives.test_wait = UserEvent::create_user_event();
  primitives.test_triggered = UserEvent::create_user_event();
  primitives.test_bar = Barrier::create_barrier(2);

  // Make sure that task launching synchronizes
  x = 11;
  // Collective launch a single task on each CPU processor of each node, that
  // just means this test will be done once on each node
  Event e = rt.collective_spawn_by_kind(Processor::LOC_PROC, TOP_LEVEL_TASK,
                      &primitives, sizeof(primitives), true/*one per node*/);
  // request shutdown once that task is complete
  rt.shutdown(e);

  // Make sure that user-event triggers synchronize with waits
  primitives.test_wait.external_wait();
  assert(x == 42);
  // Make sure that user-events synchronize with has_triggered
  x = 1729;
  primitives.test_triggered.trigger();
  // Make sure that barrier arrive and wait synchronize
  y = 23;
  primitives.test_bar.arrive();
  primitives.test_bar.wait();
  assert(x == 6174);

  // Make sure that task completion events synchronize
  e.external_wait();
  assert(y == 2520);
  // now sleep this thread until that shutdown actually happens
  rt.wait_for_shutdown();

  return 0;
}

<|endoftext|>


<commit_before>#include<iostream>
#include<cassert>
#include<thread>
#include<chrono>

#include "ics3/ics"

int main(int argc, char **argv) {
  {
    std::cout << std::endl << "ID test section" << std::endl;
    ics::ID id {0};
    assert(id == 0);
    assert(id == 0);
    ics::ID id31 {31};
    assert(id31 == 31);
    assert(id31.get() == 31);
    try {
      ics::ID id32 {32};
      assert(false);
    } catch (std::invalid_argument& e) {
      std::cout << e.what() << std::endl;
    }
  }
  {
    std::cout << std::endl << "EepParam test section" << std::endl;
    ics::EepParam speed = ics::EepParam::speed();
    assert(127 == speed.get());
    speed.set(100);
    assert(100 == speed.get());
    try {
      speed.set(200);
      std::cerr << "Never run this" << std::endl;
    } catch (std::invalid_argument& e) {
      std::cout << e.what() << std::endl;
    }
  }
  {
    std::cout << std::endl << "angle test section" << std::endl;
    ics::Angle degree = ics::Angle::newDegree();
    ics::Angle radian = ics::Angle::newRadian();
    assert(degree.getRaw() == radian.getRaw());
    degree.set(0);
    radian.set(0);
    assert(degree.getRaw() == radian.getRaw());
    degree.set(90);
    radian.set(M_PI / 2);
    assert(degree.getRaw() == radian.getRaw());
    degree.set(60);
    radian.set(M_PI / 3);
    assert(degree.getRaw() == radian.getRaw());
    try {
      degree.set(150);
      std::cerr << "Never run this" << std::endl;
    } catch (const std::invalid_argument& e) {
      std::cout << e.what() << std::endl;
    }
    try {
      radian.set(M_PI);
      std::cerr << "Never run this" << std::endl;
    } catch (const std::invalid_argument& e) {
      std::cout << e.what() << std::endl;
    }
  }
  {
    std::cout << std::endl << "angle factory test section" << std::endl;
    ics::Angle degree = ics::Angle::newDegree(90);
    ics::Angle radian = ics::Angle::newRadian(M_PI / 2);
    assert(degree.getRaw() == radian.getRaw());
  }
  {
    std::cout << std::endl << "parameter test section" << std::endl;
    ics::Parameter current = ics::Parameter::current();
    assert(63 == current.get());
    current.set(30);
    assert(30 == current.get());
    try {
      current.set(70);
      std::cerr << "Never run this" << std::endl;
    } catch (const std::invalid_argument& e) {
      std::cout << e.what() << std::endl;
    }
  }
  {
    std::cout << std::endl << "ICS3 test section" << std::endl;
    ics::ID id(2);
    ics::Angle degree = ics::Angle::newDegree();
    try {
      ics::ICS3 ics("/dev/ttyUSB0");
      assert(7500 == degree.getRaw());
      ics::Angle nowPos = ics.move(id, degree);
      std::cout << nowPos.get() << std::endl;
      std::this_thread::sleep_for(std::chrono::milliseconds(1000));
      degree.set(50);
      nowPos = ics.move(id, degree);
      std::cout << nowPos.get() << std::endl;
      std::this_thread::sleep_for(std::chrono::milliseconds(1000));
      degree.set(-50);
      nowPos = ics.move(id, degree);
      std::cout << nowPos.get() << std::endl;
      std::this_thread::sleep_for(std::chrono::milliseconds(1000));
      degree.set(0);
      nowPos = ics.move(id, degree);
      std::cout << nowPos.get() << std::endl;
      nowPos = ics.free(id);
      std::cout << nowPos.get() << std::endl;
    } catch (std::runtime_error& e) {
      std::cout << e.what() << std::endl;
    }
  }
  return 0;
}
<commit_msg>Fix test code<commit_after>#include<iostream>
#include<cassert>
#include<thread>
#include<chrono>

#include "ics3/ics"

int main(int argc, char **argv) {
  {
    std::cout << std::endl << "ID test section" << std::endl;
    ics::ID id {0};
    assert(id == 0);
    assert(id.get() == 0);
    ics::ID id31 {31};
    assert(id31 == 31);
    assert(id31.get() == 31);
    try {
      ics::ID id32 {32};
      assert(false);
    } catch (std::invalid_argument& e) {
      std::cout << e.what() << std::endl;
    }
  }
  {
    std::cout << std::endl << "EepParam test section" << std::endl;
    ics::EepParam speed = ics::EepParam::speed();
    assert(127 == speed.get());
    speed.set(100);
    assert(100 == speed.get());
    try {
      speed.set(200);
      std::cerr << "Never run this" << std::endl;
    } catch (std::invalid_argument& e) {
      std::cout << e.what() << std::endl;
    }
  }
  {
    std::cout << std::endl << "angle test section" << std::endl;
    ics::Angle degree = ics::Angle::newDegree();
    ics::Angle radian = ics::Angle::newRadian();
    assert(degree.getRaw() == radian.getRaw());
    degree.set(0);
    radian.set(0);
    assert(degree.getRaw() == radian.getRaw());
    degree.set(90);
    radian.set(M_PI / 2);
    assert(degree.getRaw() == radian.getRaw());
    degree.set(60);
    radian.set(M_PI / 3);
    assert(degree.getRaw() == radian.getRaw());
    try {
      degree.set(150);
      std::cerr << "Never run this" << std::endl;
    } catch (const std::invalid_argument& e) {
      std::cout << e.what() << std::endl;
    }
    try {
      radian.set(M_PI);
      std::cerr << "Never run this" << std::endl;
    } catch (const std::invalid_argument& e) {
      std::cout << e.what() << std::endl;
    }
  }
  {
    std::cout << std::endl << "angle factory test section" << std::endl;
    ics::Angle degree = ics::Angle::newDegree(90);
    ics::Angle radian = ics::Angle::newRadian(M_PI / 2);
    assert(degree.getRaw() == radian.getRaw());
  }
  {
    std::cout << std::endl << "parameter test section" << std::endl;
    ics::Parameter current = ics::Parameter::current();
    assert(63 == current.get());
    current.set(30);
    assert(30 == current.get());
    try {
      current.set(70);
      std::cerr << "Never run this" << std::endl;
    } catch (const std::invalid_argument& e) {
      std::cout << e.what() << std::endl;
    }
  }
  {
    std::cout << std::endl << "ICS3 test section" << std::endl;
    ics::ID id(2);
    ics::Angle degree = ics::Angle::newDegree();
    try {
      ics::ICS3 ics("/dev/ttyUSB0");
      assert(7500 == degree.getRaw());
      ics::Angle nowPos = ics.move(id, degree);
      std::cout << nowPos.get() << std::endl;
      std::this_thread::sleep_for(std::chrono::milliseconds(1000));
      degree.set(50);
      nowPos = ics.move(id, degree);
      std::cout << nowPos.get() << std::endl;
      std::this_thread::sleep_for(std::chrono::milliseconds(1000));
      degree.set(-50);
      nowPos = ics.move(id, degree);
      std::cout << nowPos.get() << std::endl;
      std::this_thread::sleep_for(std::chrono::milliseconds(1000));
      degree.set(0);
      nowPos = ics.move(id, degree);
      std::cout << nowPos.get() << std::endl;
      nowPos = ics.free(id);
      std::cout << nowPos.get() << std::endl;
    } catch (std::runtime_error& e) {
      std::cout << e.what() << std::endl;
    }
  }
  return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
#include <string.h>
#include <assert.h>

#include <mkl.h>

#include "winconv.hpp"
#include <time.h>
#include <stdint.h>
#include <sys/time.h>
#include <unistd.h>
#define icrt_time_sec() ({ struct timeval tp; gettimeofday(&tp, 0); tp.tv_sec + tp. tv_usec * 1.e-6; })

#define CYCLE_NUM		100

#define F_2X3			1
//#define F_3X3			2
//#define F_HYBRID		3

int counter = 0;

int myDirectConv(float *in, float *kn, float *out,
		const int N, const int C, const int H, const int W, const int K)
{
	int inpos, knpos, outpos;

	int dimIn[4]  = {N, C, H, W};
	int dimKn[4]  = {K, C, 3, 3};
	int dimOut[4] = {N, K, H-2, W-2};

	int ingap[3] = {dimIn[1]*dimIn[2]*dimIn[3], dimIn[2]*dimIn[3], dimIn[3]};
	int kngap[3] = {dimKn[1]*dimKn[2]*dimKn[3], dimKn[2]*dimKn[3], dimKn[3]};
	int outgap[3] = {dimOut[1]*dimOut[2]*dimOut[3], dimOut[2]*dimOut[3], dimOut[3]};

	#pragma omp parallel for private(inpos, knpos, outpos)
	for(int inn = 0; inn < dimIn[0]; inn++)
		for(int knn = 0; knn < dimKn[0]; knn++)
			for(int inc = 0; inc < dimIn[1]; inc++){
				for(int outh = 0; outh < dimOut[2]; outh++)
					for(int outw = 0; outw < dimOut[3]; outw++){
						outpos = inn*outgap[0] + knn*outgap[1] + outh*outgap[2] + outw;
							for(int knh = 0; knh < dimKn[2]; knh++)
								for(int knw = 0; knw < dimKn[3]; knw++){
									inpos = inn*ingap[0] + inc*ingap[1] + (outh+knh)*ingap[2] + (outw+knw);
									//knpos = knn*kngap[0] + inc*kngap[1] + 8 - (knh*kngap[2] + knw);
									knpos = knn*kngap[0] + inc*kngap[1] + knh*kngap[2] + knw;
									out[outpos] += in[inpos] * kn[knpos];
								}
					}
			}

	return 0;
}

void winograd_conv(const int bblock2x3, const int M2x3,
		int irows, int icols,int C, int K, const int batch,
		long* total_flops, double* total_time, const int verify){
	counter++;

    long i, j, n;
    const int outHeight = irows-2;
    const int outWidth = icols-2;
    const int sizeI = irows*icols;
    const int sizeF = 3*3;
    const int sizeO = outHeight*outWidth;
    const int tiles = (outHeight)*0.5*(outWidth)*0.5;

    int ret;

    float* image, *filter, *out;
	image = (float *)mkl_malloc(batch*C*sizeI*sizeof(float), 64);
    assert(image != NULL);
	filter = (float *)mkl_malloc(K*C*sizeF*sizeof(float), 64);
    assert(filter != NULL);
	out = (float *)mkl_malloc(batch*K*sizeO*sizeof(float), 64);
    assert(out != NULL);

    //initialize image in parallel
    #pragma omp parallel for private(i)
    for(i = 0; i < batch*C*sizeI; i++)
        image[i] = (float)(i%11);
        //image[i] = rand()%5;

    //initialize image in parallel
    #pragma omp parallel for private(i)
    for(i = 0; i < K*C*sizeF; i++)
        filter[i] = (float)(i%7);
        //filter[i] = rand()%3;

    double timer;
    double timer_acc = 0.0f;

    double stime, etime;

    /* First Time */
    winconv_2x3(bblock2x3, M2x3, image, irows, icols, C, filter, K, batch, out);

    stime = icrt_time_sec();
    for(i = 0; i < CYCLE_NUM; i++){
	winconv_2x3(bblock2x3, M2x3, image, irows, icols, C, filter, K, batch, out);
    }
    etime = icrt_time_sec();

    timer_acc = etime - stime;

    timer = timer_acc/CYCLE_NUM;
    long nflops = batch*K*C*(irows-2)*(icols-2)*3*3*2;
    double gflops = (double) nflops*1.0e-9/timer;
    *total_flops += nflops;
    *total_time += timer;

    if(verify){
	float* vout = (float *)malloc(batch*K*sizeO*sizeof(float));
	memset(vout, 0, batch*K*sizeO*sizeof(float));

	myDirectConv(image, filter, vout, batch, C, irows, icols, K);
	printf("CONV[%-2d], N-C-H-W-K-(Merge2x3-Block2x3) = %-3d %-3d %-3d %-3d %-3d (%-3d %-2d) : ",
			counter, batch, C, irows, icols, K, M2x3, bblock2x3 );
	for(n = 0; n < batch*sizeO*K; n++){
            if(fabs((out[n] - vout[n])/vout[n]) > 1e-4){
                printf("Output Error!!! winogradConv[%d] = %f || directConv[%d] = %f \n", n, out[n], n, vout[n]);
                break;
            }
        }
	if(n == batch*sizeO*K)
 	    printf("Output  True!!!\n");
	    free(vout);
    }
    else{
        printf("CONV[%d]:\tEFFECTIVE GFLOPS is %7.2f \tGFlops \tand timing is \t%f  ms \n", counter, gflops, timer*1000);
    }

    mkl_free(image);
    mkl_free(filter);
    mkl_free(out);

}

int main(int argc, char** argv){

    if(argc < 2){
        printf("Enter the running mode\n");
        printf("Example: ./test  0 or ./test  1\n");
    //    exit(-1);
    }
    int i, j;
    double timer;

    int verify = 0; //fix me
    if(argc>1)
	verify = atoi(argv[1]);

    //const int max_tiles = 224*224*0.25;
    const long max_tiles = MAX_TILES;

    const int layer_num = 18;
    const int C_array[18] = {1, 32, 64, 64, 128, 128, 256, 256, 512, 512, 3, 32, 64, 64, 128, 96, 128, 128};
    const int IH_array[18] = {40, 20, 20, 10, 10, 6, 6, 6, 6, 6, 100, 100, 50, 50, 20, 12, 12, 8};
    const int IW_array[18] = {1024, 512, 512, 512, 512, 512, 512, 512, 512, 1024, 100, 100, 50, 50, 26, 12, 12, 8};
    const int K_array[18] = {32, 64, 64, 128, 128, 256, 256, 512, 512, 2048, 32, 64, 64, 128, 96, 192, 256, 512};
    const int Batch_array[18] = {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 128, 128, 128, 128, 128, 128, 128, 128};
    int merge_array2x3[18] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
    int b_block2x3[18];

    int t;
    double total_time;
    long total_flops;
    int batch = 64;
   /* for(t = 0; t < layer_num; t++){
        if(batch<Batch_array[t])
        batch=Batch_array[t];
    }*/

    compute_max_stride(layer_num, batch, C_array, IH_array, IW_array, K_array);
    decide_batch_block(layer_num, batch, C_array, IH_array, IW_array, K_array, b_block2x3);
    winconv_init_lib();

    /* Compute Convoltuion Using F(2,3) Winograd */
    total_time = 0.0f;
    total_flops = 0;
    if(verify)
		printf("========== Verify Winograd Conv correctness for F(2,3)  ==========\n");
    else
		printf("========== Test WINOGRAD CONV Performance for F(2,3) ==========\n");
    for(t = 0; t < layer_num; t++){
        int irows = IH_array[t];
	int icols = IW_array[t];
        int C = C_array[t];
        int K = K_array[t];
        int batch = Batch_array[t];
        winograd_conv(b_block2x3[t], merge_array2x3[t],
		irows, icols, C, K, batch, &total_flops, &total_time, verify);
    }
    if(!verify){
        printf("WINOGRAD: OVERALL EFFECTIVE GFLOPS is %.2f GFLops and Timing is %.4f ms \n", (double)total_flops*1.0e-9/total_time, total_time*1000);
    }
    printf("\n *******************************************************************\n\n");

    winconv_free_lib();

    return 0;
}
<commit_msg>modify merge parameter<commit_after>#include <iostream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
#include <string.h>
#include <assert.h>

#include <mkl.h>

#include "winconv.hpp"
#include <time.h>
#include <stdint.h>
#include <sys/time.h>
#include <unistd.h>
#define icrt_time_sec() ({ struct timeval tp; gettimeofday(&tp, 0); tp.tv_sec + tp. tv_usec * 1.e-6; })

#define CYCLE_NUM		100

#define F_2X3			1
//#define F_3X3			2
//#define F_HYBRID		3

int counter = 0;

int myDirectConv(float *in, float *kn, float *out,
		const int N, const int C, const int H, const int W, const int K)
{
	int inpos, knpos, outpos;

	int dimIn[4]  = {N, C, H, W};
	int dimKn[4]  = {K, C, 3, 3};
	int dimOut[4] = {N, K, H-2, W-2};

	int ingap[3] = {dimIn[1]*dimIn[2]*dimIn[3], dimIn[2]*dimIn[3], dimIn[3]};
	int kngap[3] = {dimKn[1]*dimKn[2]*dimKn[3], dimKn[2]*dimKn[3], dimKn[3]};
	int outgap[3] = {dimOut[1]*dimOut[2]*dimOut[3], dimOut[2]*dimOut[3], dimOut[3]};

	#pragma omp parallel for private(inpos, knpos, outpos)
	for(int inn = 0; inn < dimIn[0]; inn++)
		for(int knn = 0; knn < dimKn[0]; knn++)
			for(int inc = 0; inc < dimIn[1]; inc++){
				for(int outh = 0; outh < dimOut[2]; outh++)
					for(int outw = 0; outw < dimOut[3]; outw++){
						outpos = inn*outgap[0] + knn*outgap[1] + outh*outgap[2] + outw;
							for(int knh = 0; knh < dimKn[2]; knh++)
								for(int knw = 0; knw < dimKn[3]; knw++){
									inpos = inn*ingap[0] + inc*ingap[1] + (outh+knh)*ingap[2] + (outw+knw);
									//knpos = knn*kngap[0] + inc*kngap[1] + 8 - (knh*kngap[2] + knw);
									knpos = knn*kngap[0] + inc*kngap[1] + knh*kngap[2] + knw;
									out[outpos] += in[inpos] * kn[knpos];
								}
					}
			}

	return 0;
}

void winograd_conv(const int bblock2x3, const int M2x3,
		int irows, int icols,int C, int K, const int batch,
		long* total_flops, double* total_time, const int verify){
	counter++;

    long i, j, n;
    const int outHeight = irows-2;
    const int outWidth = icols-2;
    const int sizeI = irows*icols;
    const int sizeF = 3*3;
    const int sizeO = outHeight*outWidth;
    const int tiles = (outHeight)*0.5*(outWidth)*0.5;

    int ret;

    float* image, *filter, *out;
	image = (float *)mkl_malloc(batch*C*sizeI*sizeof(float), 64);
    assert(image != NULL);
	filter = (float *)mkl_malloc(K*C*sizeF*sizeof(float), 64);
    assert(filter != NULL);
	out = (float *)mkl_malloc(batch*K*sizeO*sizeof(float), 64);
    assert(out != NULL);

    //initialize image in parallel
    #pragma omp parallel for private(i)
    for(i = 0; i < batch*C*sizeI; i++)
        image[i] = (float)(i%11);
        //image[i] = rand()%5;

    //initialize image in parallel
    #pragma omp parallel for private(i)
    for(i = 0; i < K*C*sizeF; i++)
        filter[i] = (float)(i%7);
        //filter[i] = rand()%3;

    double timer;
    double timer_acc = 0.0f;

    double stime, etime;

    /* First Time */
    winconv_2x3(bblock2x3, M2x3, image, irows, icols, C, filter, K, batch, out);

    stime = icrt_time_sec();
    for(i = 0; i < CYCLE_NUM; i++){
	winconv_2x3(bblock2x3, M2x3, image, irows, icols, C, filter, K, batch, out);
    }
    etime = icrt_time_sec();

    timer_acc = etime - stime;

    timer = timer_acc/CYCLE_NUM;
    long nflops = batch*K*C*(irows-2)*(icols-2)*3*3*2;
    double gflops = (double) nflops*1.0e-9/timer;
    *total_flops += nflops;
    *total_time += timer;

    if(verify){
	float* vout = (float *)malloc(batch*K*sizeO*sizeof(float));
	memset(vout, 0, batch*K*sizeO*sizeof(float));

	myDirectConv(image, filter, vout, batch, C, irows, icols, K);
	printf("CONV[%-2d], N-C-H-W-K-(Merge2x3-Block2x3) = %-3d %-3d %-3d %-3d %-3d (%-3d %-2d) : ",
			counter, batch, C, irows, icols, K, M2x3, bblock2x3 );
	for(n = 0; n < batch*sizeO*K; n++){
            if(fabs((out[n] - vout[n])/vout[n]) > 1e-4){
                printf("Output Error!!! winogradConv[%d] = %f || directConv[%d] = %f \n", n, out[n], n, vout[n]);
                break;
            }
        }
	if(n == batch*sizeO*K)
 	    printf("Output  True!!!\n");
	    free(vout);
    }
    else{
        printf("CONV[%d]:\tEFFECTIVE GFLOPS is %7.2f \tGFlops \tand timing is \t%f  ms \n", counter, gflops, timer*1000);
    }

    mkl_free(image);
    mkl_free(filter);
    mkl_free(out);

}

int main(int argc, char** argv){

    if(argc < 2){
        printf("Enter the running mode\n");
        printf("Example: ./test  0 or ./test  1\n");
    //    exit(-1);
    }
    int i, j;
    double timer;

    int verify = 0; //fix me
    if(argc>1)
	verify = atoi(argv[1]);

    //const int max_tiles = 224*224*0.25;
    const long max_tiles = MAX_TILES;

    const int layer_num = 18;
    const int C_array[18] = {1, 32, 64, 64, 128, 128, 256, 256, 512, 512, 3, 32, 64, 64, 128, 96, 128, 128};
    const int IH_array[18] = {40, 20, 20, 10, 10, 6, 6, 6, 6, 6, 100, 100, 50, 50, 20, 12, 12, 8};
    const int IW_array[18] = {1024, 512, 512, 512, 512, 512, 512, 512, 512, 1024, 100, 100, 50, 50, 26, 12, 12, 8};
    const int K_array[18] = {32, 64, 64, 128, 128, 256, 256, 512, 512, 2048, 32, 64, 64, 128, 96, 192, 256, 512};
    const int Batch_array[18] = {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 128, 128, 128, 128, 128, 128, 128, 128};
    int merge_array2x3[18] = {1, 1, 1, 1, 1, 1, 4, 4, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1};
    int b_block2x3[18];

    int t;
    double total_time;
    long total_flops;
    int batch = 64;
   /* for(t = 0; t < layer_num; t++){
        if(batch<Batch_array[t])
        batch=Batch_array[t];
    }*/

    compute_max_stride(layer_num, batch, C_array, IH_array, IW_array, K_array);
    decide_batch_block(layer_num, batch, C_array, IH_array, IW_array, K_array, b_block2x3);
    winconv_init_lib();

    /* Compute Convoltuion Using F(2,3) Winograd */
    total_time = 0.0f;
    total_flops = 0;
    if(verify)
		printf("========== Verify Winograd Conv correctness for F(2,3)  ==========\n");
    else
		printf("========== Test WINOGRAD CONV Performance for F(2,3) ==========\n");
    for(t = 0; t < layer_num; t++){
        int irows = IH_array[t];
	int icols = IW_array[t];
        int C = C_array[t];
        int K = K_array[t];
        int batch = Batch_array[t];
        winograd_conv(b_block2x3[t], merge_array2x3[t],
		irows, icols, C, K, batch, &total_flops, &total_time, verify);
    }
    if(!verify){
        printf("WINOGRAD: OVERALL EFFECTIVE GFLOPS is %.2f GFLops and Timing is %.4f ms \n", (double)total_flops*1.0e-9/total_time, total_time*1000);
    }
    printf("\n *******************************************************************\n\n");

    winconv_free_lib();

    return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: slideshowimpl.hxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: obo $ $Date: 2005-10-11 08:18:14 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SD_SLIDESHOWIMPL_HXX_
#define _SD_SLIDESHOWIMPL_HXX_

#ifndef _CPPUHELPER_COMPBASE2_HXX_
#include <cppuhelper/compbase2.hxx>
#endif
#ifndef _COMPHELPER_BROADCASTHELPER_HXX_
#include <comphelper/broadcasthelper.hxx>
#endif
#ifndef COMPHELPER_INC_COMPHELPER_LISTENERNOTIFICATION_HXX
#include <comphelper/listenernotification.hxx>
#endif

#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/helper/vclunohelper.hxx>
#endif
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif

#ifndef _COM_SUN_STAR_AWT_WINDOWEVENT_HPP_
#include <com/sun/star/awt/WindowEvent.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XWINDOWLISTENER_HPP_
#include <com/sun/star/awt/XWindowListener.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
#include <com/sun/star/awt/XWindow.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XWINDOWPEER_HPP_
#include <com/sun/star/awt/XWindowPeer.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XMODIFYLISTENER_HPP_
#include <com/sun/star/util/XModifyListener.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XPAINTLISTENER_HPP_
#include <com/sun/star/awt/XPaintListener.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XPOINTER_HPP_
#include <com/sun/star/awt/XPointer.hpp>
#endif
#ifndef _COM_SUN_STAR_PRESENTATION_XSLIDESHOW_HPP_
#include <com/sun/star/presentation/XSlideShow.hpp>
#endif
#ifndef _COM_SUN_STAR_PRESENTATION_XSLIDESHOWVIEW_HPP_
#include <com/sun/star/presentation/XSlideShowView.hpp>
#endif
#ifndef _COM_SUN_STAR_PRESENTATION_XSLIDESHOWLISTENER_HPP_
#include <com/sun/star/presentation/XSlideShowListener.hpp>
#endif
#ifndef _COM_SUN_STAR_PRESENTATION_XSHAPEEVENTLISTENER_HPP_
#include <com/sun/star/presentation/XShapeEventListener.hpp>
#endif
#ifndef _COM_SUN_STAR_DRAWING_XDRAWPAGESSUPPLIER_HPP_
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_ANIMATIONS_XANIMATIONNODESUPPLIER_HPP_
#include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_PRESENTATION_CLICKACTION_HPP_
#include <com/sun/star/presentation/ClickAction.hpp>
#endif
#ifndef _COM_SUN_STAR_MEDIA_XMANAGER_HPP_
#include <com/sun/star/media/XManager.hpp>
#endif
#ifndef _COM_SUN_STAR_MEDIA_XPLAYER_HPP_
#include <com/sun/star/media/XPlayer.hpp>
#endif

#ifndef _COMPHELPER_IMPLEMENTATIONREFERENCE_HXX
#include <comphelper/implementationreference.hxx>
#endif

#ifndef _BGFX_MATRIX_B2DHOMMATRIX_HXX
#include <basegfx/matrix/b2dhommatrix.hxx>
#endif
#ifndef _BGFX_TOOLS_CANVASTOOLS_HXX
#include <basegfx/tools/canvastools.hxx>
#endif

#ifndef _SV_HELP_HXX //autogen
#include <vcl/help.hxx>
#endif

#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif

#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif

#ifndef INCLUDED_SVTOOLS_SAVEOPT_HXX
#include <svtools/saveopt.hxx>
#endif

#ifndef _SFX_BINDINGS_HXX //autogen
#include <sfx2/bindings.hxx>
#endif

#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif

#ifndef _SFXVIEWFRM_HXX
#include <sfx2/viewfrm.hxx>
#endif

#ifndef _SB_SBSTAR_HXX //autogen
#include <basic/sbstar.hxx>
#endif

#ifndef _SVDPAGV_HXX
#include <svx/svdpagv.hxx>
#endif

#ifndef _SVX_FMSHELL_HXX
#include <svx/fmshell.hxx>
#endif

#ifndef _SVX_SVXIDS_HRC
#include <svx/svxids.hrc>
#endif

#ifndef _SDMOD_HXX
#include "sdmod.hxx"
#endif

#ifndef _SD_CUSSHOW_HXX
#include "cusshow.hxx"
#endif

#ifndef SD_VIEW_SHELL_BASE_HXX
#include "ViewShellBase.hxx"
#endif

#ifndef SD_PRESENTATION_VIEW_SHELL_HXX
#include "PresentationViewShell.hxx"
#endif

#ifndef SD_VIEW_SHELL_HXX
#include "ViewShell.hxx"
#endif

#ifndef SD_DRAW_VIEW_HXX
#include "drawview.hxx"
#endif

#ifndef _DRAWDOC_HXX
#include "drawdoc.hxx"
#endif

#ifndef SD_SHOW_WINDOW_HXX
#include "ShowWindow.hxx"
#endif

#ifndef _SD_OPTSITEM_HXX
#include "optsitem.hxx"
#endif

#ifndef SD_OBJECT_BAR_MANAGER_HXX
#include "ObjectBarManager.hxx"
#endif

#ifndef SD_FRAME_VIEW_HXX
#include "FrameView.hxx"
#endif

#ifndef SD_DRAW_DOC_SHELL_HXX
#include "DrawDocShell.hxx"
#endif

#ifndef _SD_APP_HRC_
#include "app.hrc"
#endif

#include "slideshow.hxx"

class SfxViewFrame;
class SfxRequest;

namespace sd
{
class SlideShowView;
class AnimationSlideController;
class PaneHider;

struct WrappedShapeEventImpl
{
    ::com::sun::star::presentation::ClickAction meClickAction;
    sal_Int32 mnVerb;
    ::rtl::OUString maStrBookmark;
    WrappedShapeEventImpl() : meClickAction( ::com::sun::star::presentation::ClickAction_NONE ), mnVerb( 0 ) {};
};

typedef boost::shared_ptr< WrappedShapeEventImpl > WrappedShapeEventImplPtr;
typedef std::map< ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >, WrappedShapeEventImplPtr > WrappedShapeEventImplMap;

typedef ::cppu::WeakComponentImplHelper2< ::com::sun::star::presentation::XShapeEventListener,
        ::com::sun::star::presentation::XSlideShowListener > SlideshowImpl_base;

class SlideshowImpl : public ::comphelper::OBaseMutex, public SlideshowImpl_base
{
    friend class Slideshow;
public:
    SlideshowImpl( ViewShell* pViewSh, ::sd::View* pView, SdDrawDocument* pDoc );
    ~SlideshowImpl();

    bool startShow( PresentationSettings* pPresSettings );
    bool startPreview(
        const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& xDrawPage,
        const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xAnimationNode,
        ::Window* pParent = 0 );

    void stopShow();

    double update();
    /** forces an async call to update in the main thread */
    void startUpdateTimer();
    void paint( const Rectangle& rRect );
    bool keyInput(const KeyEvent& rKEvt);
    void mouseButtonUp(const MouseEvent& rMEvt);

    void createSlideList( bool bAll, bool bStartWithActualSlide, const String& rPresSlide );

    void stopSound();

    void displayCurrentSlide();

    void displaySlideNumber( sal_Int32 nSlide );
    void displaySlideIndex( sal_Int32 nIndex );
    sal_Int32 getCurrentSlideNumber();
    sal_Int32 getCurrentSlideIndex();
    sal_Int32 getFirstSlideNumber();
    sal_Int32 getLastSlideNumber();
    bool isEndless();
    bool isDrawingPossible();
    inline bool isInputFreezed() const;

    void jumpToBookmark( const String& sBookmark );

    void activate();
    void deactivate();

    void hideChildWindows();
    void showChildWindows();

    void resize( const Size& rSize );

    DECL_LINK( updateHdl, Timer* );
    DECL_LINK( ReadyForNextInputHdl, Timer* );
    DECL_LINK( endPresentationHdl, void* );

    // XShapeEventListener
    virtual void SAL_CALL click( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xShape, const ::com::sun::star::awt::MouseEvent& aOriginalEvent ) throw (::com::sun::star::uno::RuntimeException);

    // XSlideShowListener
    virtual void SAL_CALL slideEnded() throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL hyperLinkClicked( ::rtl::OUString const& hyperLink )
        throw (::com::sun::star::uno::RuntimeException);

    // XEventListener
    virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);

    // helper
    void gotoPreviousSlide();
    void gotoNextSlide();
    void gotoFirstSlide();
    void gotoLastSlide();
    void endPresentation();
    void enablePen();

    bool pause( bool bPause );

    void receiveRequest(SfxRequest& rReq);

    /** called only by the slideshow view when the first paint event occurs.
        This actually starts the slideshow. */
    void onFirstPaint();

    ShowWindow* getShowWindow() const { return mpShowWindow; }

private:
    bool startShowImpl(
        const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProperties );

    SfxViewFrame* getViewFrame() const;

    sal_Int32 getSlideNumberForBookmark( const rtl::OUString& rStrBookmark );

    void removeShapeEvents();
    void registerShapeEvents( sal_Int32 nSlideNumber );
    void registerShapeEvents( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xShapes ) throw (::com::sun::star::uno::Exception);

    // default: disabled copy/assignment
    SlideshowImpl(const SlideshowImpl&);
    SlideshowImpl& operator=( const SlideshowImpl& );

    ::com::sun::star::uno::Reference< ::com::sun::star::presentation::XSlideShow > createSlideShow() const;

    ::com::sun::star::uno::Reference< ::com::sun::star::presentation::XSlideShow > mxShow;
    comphelper::ImplementationReference< ::sd::SlideShowView, ::com::sun::star::presentation::XSlideShowView > mxView;
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > mxModel;

    Timer maUpdateTimer;
    Timer maInputFreezeTimer;

    ::sd::View* mpView;
    ViewShell* mpViewShell;
    DrawDocShell* mpDocSh;
    SdDrawDocument* mpDoc;

    SfxItemSet*     mpNewAttr;
    ShowWindow*     mpShowWindow;
    SvtSaveOptions* mpSaveOptions;
    PushButton*     mpTimeButton;

    boost::shared_ptr< AnimationSlideController > mpSlideController;

    long            mnRestoreSlide;
    Point           maSlideOrigin;
    Size            maSlideSize;
    Size            maPresSize;
    AnimationMode   meAnimationMode;
    String          maCharBuffer;
    Pointer         maOldPointer;
    Pointer         maPencil;
    std::vector< ::sd::Window* > maDrawModeWindows;
    ::sd::Window*   mpOldActiveWindow;
    Link            maStarBASICGlobalErrorHdl;
    unsigned long   mnChildMask;
    bool            mbGridVisible;
    bool            mbBordVisible;
    bool            mbSlideBorderVisible;
    bool            mbSetOnlineSpelling;
    bool            mbDisposed;
    bool            mbMouseIsDrawing;
    bool            mbAutoSaveSuppressed;
    bool            mbRehearseTimings;
    bool            mbDesignMode;
    bool            mbIsPaused;
    bool            mbInputFreeze;

    PresentationSettings maPresSettings;

    /// used in updateHdl to prevent recursive calls
    sal_Int32       mnEntryCounter;

    sal_Int32       mnLastSlideNumber;
    WrappedShapeEventImplMap    maShapeEventMap;

    ::rtl::OUString msOnClick;
    ::rtl::OUString msBookmark;
    ::rtl::OUString msVerb;

    ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > mxPreviewDrawPage;
    ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode > mxPreviewAnimationNode;

    ::com::sun::star::uno::Reference< ::com::sun::star::media::XPlayer > mxPlayer;
    ::com::sun::star::uno::Reference< ::com::sun::star::media::XManager > mxManager;

    ::std::auto_ptr<PaneHider> mpPaneHider;

    ULONG   mnEndShowEvent;
};

class SlideShowImplGuard
{
public:
    SlideShowImplGuard( SlideshowImpl* pImpl );
    ~SlideShowImplGuard();

private:
    SlideshowImpl* mpImpl;
};

bool SlideshowImpl::isInputFreezed() const
{
    return mbInputFreeze;
}

} // namespace ::sd

#endif
<commit_msg>INTEGRATION: CWS viewswitch (1.15.48); FILE MERGED 2005/11/17 14:43:20 af 1.15.48.1: #i57551# Removed unused header.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: slideshowimpl.hxx,v $
 *
 *  $Revision: 1.16 $
 *
 *  last change: $Author: obo $ $Date: 2006-03-21 17:30:03 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SD_SLIDESHOWIMPL_HXX_
#define _SD_SLIDESHOWIMPL_HXX_

#ifndef _CPPUHELPER_COMPBASE2_HXX_
#include <cppuhelper/compbase2.hxx>
#endif
#ifndef _COMPHELPER_BROADCASTHELPER_HXX_
#include <comphelper/broadcasthelper.hxx>
#endif
#ifndef COMPHELPER_INC_COMPHELPER_LISTENERNOTIFICATION_HXX
#include <comphelper/listenernotification.hxx>
#endif

#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/helper/vclunohelper.hxx>
#endif
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif

#ifndef _COM_SUN_STAR_AWT_WINDOWEVENT_HPP_
#include <com/sun/star/awt/WindowEvent.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XWINDOWLISTENER_HPP_
#include <com/sun/star/awt/XWindowListener.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
#include <com/sun/star/awt/XWindow.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XWINDOWPEER_HPP_
#include <com/sun/star/awt/XWindowPeer.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XMODIFYLISTENER_HPP_
#include <com/sun/star/util/XModifyListener.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XPAINTLISTENER_HPP_
#include <com/sun/star/awt/XPaintListener.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XPOINTER_HPP_
#include <com/sun/star/awt/XPointer.hpp>
#endif
#ifndef _COM_SUN_STAR_PRESENTATION_XSLIDESHOW_HPP_
#include <com/sun/star/presentation/XSlideShow.hpp>
#endif
#ifndef _COM_SUN_STAR_PRESENTATION_XSLIDESHOWVIEW_HPP_
#include <com/sun/star/presentation/XSlideShowView.hpp>
#endif
#ifndef _COM_SUN_STAR_PRESENTATION_XSLIDESHOWLISTENER_HPP_
#include <com/sun/star/presentation/XSlideShowListener.hpp>
#endif
#ifndef _COM_SUN_STAR_PRESENTATION_XSHAPEEVENTLISTENER_HPP_
#include <com/sun/star/presentation/XShapeEventListener.hpp>
#endif
#ifndef _COM_SUN_STAR_DRAWING_XDRAWPAGESSUPPLIER_HPP_
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_ANIMATIONS_XANIMATIONNODESUPPLIER_HPP_
#include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_PRESENTATION_CLICKACTION_HPP_
#include <com/sun/star/presentation/ClickAction.hpp>
#endif
#ifndef _COM_SUN_STAR_MEDIA_XMANAGER_HPP_
#include <com/sun/star/media/XManager.hpp>
#endif
#ifndef _COM_SUN_STAR_MEDIA_XPLAYER_HPP_
#include <com/sun/star/media/XPlayer.hpp>
#endif

#ifndef _COMPHELPER_IMPLEMENTATIONREFERENCE_HXX
#include <comphelper/implementationreference.hxx>
#endif

#ifndef _BGFX_MATRIX_B2DHOMMATRIX_HXX
#include <basegfx/matrix/b2dhommatrix.hxx>
#endif
#ifndef _BGFX_TOOLS_CANVASTOOLS_HXX
#include <basegfx/tools/canvastools.hxx>
#endif

#ifndef _SV_HELP_HXX //autogen
#include <vcl/help.hxx>
#endif

#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif

#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif

#ifndef INCLUDED_SVTOOLS_SAVEOPT_HXX
#include <svtools/saveopt.hxx>
#endif

#ifndef _SFX_BINDINGS_HXX //autogen
#include <sfx2/bindings.hxx>
#endif

#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif

#ifndef _SFXVIEWFRM_HXX
#include <sfx2/viewfrm.hxx>
#endif

#ifndef _SB_SBSTAR_HXX //autogen
#include <basic/sbstar.hxx>
#endif

#ifndef _SVDPAGV_HXX
#include <svx/svdpagv.hxx>
#endif

#ifndef _SVX_FMSHELL_HXX
#include <svx/fmshell.hxx>
#endif

#ifndef _SVX_SVXIDS_HRC
#include <svx/svxids.hrc>
#endif

#ifndef _SDMOD_HXX
#include "sdmod.hxx"
#endif

#ifndef _SD_CUSSHOW_HXX
#include "cusshow.hxx"
#endif

#ifndef SD_VIEW_SHELL_BASE_HXX
#include "ViewShellBase.hxx"
#endif

#ifndef SD_PRESENTATION_VIEW_SHELL_HXX
#include "PresentationViewShell.hxx"
#endif

#ifndef SD_VIEW_SHELL_HXX
#include "ViewShell.hxx"
#endif

#ifndef SD_DRAW_VIEW_HXX
#include "drawview.hxx"
#endif

#ifndef _DRAWDOC_HXX
#include "drawdoc.hxx"
#endif

#ifndef SD_SHOW_WINDOW_HXX
#include "ShowWindow.hxx"
#endif

#ifndef _SD_OPTSITEM_HXX
#include "optsitem.hxx"
#endif

#ifndef SD_FRAME_VIEW_HXX
#include "FrameView.hxx"
#endif

#ifndef SD_DRAW_DOC_SHELL_HXX
#include "DrawDocShell.hxx"
#endif

#ifndef _SD_APP_HRC_
#include "app.hrc"
#endif

#include "slideshow.hxx"

class SfxViewFrame;
class SfxRequest;

namespace sd
{
class SlideShowView;
class AnimationSlideController;
class PaneHider;

struct WrappedShapeEventImpl
{
    ::com::sun::star::presentation::ClickAction meClickAction;
    sal_Int32 mnVerb;
    ::rtl::OUString maStrBookmark;
    WrappedShapeEventImpl() : meClickAction( ::com::sun::star::presentation::ClickAction_NONE ), mnVerb( 0 ) {};
};

typedef boost::shared_ptr< WrappedShapeEventImpl > WrappedShapeEventImplPtr;
typedef std::map< ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >, WrappedShapeEventImplPtr > WrappedShapeEventImplMap;

typedef ::cppu::WeakComponentImplHelper2< ::com::sun::star::presentation::XShapeEventListener,
        ::com::sun::star::presentation::XSlideShowListener > SlideshowImpl_base;

class SlideshowImpl : public ::comphelper::OBaseMutex, public SlideshowImpl_base
{
    friend class Slideshow;
public:
    SlideshowImpl( ViewShell* pViewSh, ::sd::View* pView, SdDrawDocument* pDoc );
    ~SlideshowImpl();

    bool startShow( PresentationSettings* pPresSettings );
    bool startPreview(
        const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& xDrawPage,
        const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xAnimationNode,
        ::Window* pParent = 0 );

    void stopShow();

    double update();
    /** forces an async call to update in the main thread */
    void startUpdateTimer();
    void paint( const Rectangle& rRect );
    bool keyInput(const KeyEvent& rKEvt);
    void mouseButtonUp(const MouseEvent& rMEvt);

    void createSlideList( bool bAll, bool bStartWithActualSlide, const String& rPresSlide );

    void stopSound();

    void displayCurrentSlide();

    void displaySlideNumber( sal_Int32 nSlide );
    void displaySlideIndex( sal_Int32 nIndex );
    sal_Int32 getCurrentSlideNumber();
    sal_Int32 getCurrentSlideIndex();
    sal_Int32 getFirstSlideNumber();
    sal_Int32 getLastSlideNumber();
    bool isEndless();
    bool isDrawingPossible();
    inline bool isInputFreezed() const;

    void jumpToBookmark( const String& sBookmark );

    void activate();
    void deactivate();

    void hideChildWindows();
    void showChildWindows();

    void resize( const Size& rSize );

    DECL_LINK( updateHdl, Timer* );
    DECL_LINK( ReadyForNextInputHdl, Timer* );
    DECL_LINK( endPresentationHdl, void* );

    // XShapeEventListener
    virtual void SAL_CALL click( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xShape, const ::com::sun::star::awt::MouseEvent& aOriginalEvent ) throw (::com::sun::star::uno::RuntimeException);

    // XSlideShowListener
    virtual void SAL_CALL slideEnded() throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL hyperLinkClicked( ::rtl::OUString const& hyperLink )
        throw (::com::sun::star::uno::RuntimeException);

    // XEventListener
    virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);

    // helper
    void gotoPreviousSlide();
    void gotoNextSlide();
    void gotoFirstSlide();
    void gotoLastSlide();
    void endPresentation();
    void enablePen();

    bool pause( bool bPause );

    void receiveRequest(SfxRequest& rReq);

    /** called only by the slideshow view when the first paint event occurs.
        This actually starts the slideshow. */
    void onFirstPaint();

    ShowWindow* getShowWindow() const { return mpShowWindow; }

private:
    bool startShowImpl(
        const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProperties );

    SfxViewFrame* getViewFrame() const;

    sal_Int32 getSlideNumberForBookmark( const rtl::OUString& rStrBookmark );

    void removeShapeEvents();
    void registerShapeEvents( sal_Int32 nSlideNumber );
    void registerShapeEvents( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xShapes ) throw (::com::sun::star::uno::Exception);

    // default: disabled copy/assignment
    SlideshowImpl(const SlideshowImpl&);
    SlideshowImpl& operator=( const SlideshowImpl& );

    ::com::sun::star::uno::Reference< ::com::sun::star::presentation::XSlideShow > createSlideShow() const;

    ::com::sun::star::uno::Reference< ::com::sun::star::presentation::XSlideShow > mxShow;
    comphelper::ImplementationReference< ::sd::SlideShowView, ::com::sun::star::presentation::XSlideShowView > mxView;
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > mxModel;

    Timer maUpdateTimer;
    Timer maInputFreezeTimer;

    ::sd::View* mpView;
    ViewShell* mpViewShell;
    DrawDocShell* mpDocSh;
    SdDrawDocument* mpDoc;

    SfxItemSet*     mpNewAttr;
    ShowWindow*     mpShowWindow;
    SvtSaveOptions* mpSaveOptions;
    PushButton*     mpTimeButton;

    boost::shared_ptr< AnimationSlideController > mpSlideController;

    long            mnRestoreSlide;
    Point           maSlideOrigin;
    Size            maSlideSize;
    Size            maPresSize;
    AnimationMode   meAnimationMode;
    String          maCharBuffer;
    Pointer         maOldPointer;
    Pointer         maPencil;
    std::vector< ::sd::Window* > maDrawModeWindows;
    ::sd::Window*   mpOldActiveWindow;
    Link            maStarBASICGlobalErrorHdl;
    unsigned long   mnChildMask;
    bool            mbGridVisible;
    bool            mbBordVisible;
    bool            mbSlideBorderVisible;
    bool            mbSetOnlineSpelling;
    bool            mbDisposed;
    bool            mbMouseIsDrawing;
    bool            mbAutoSaveSuppressed;
    bool            mbRehearseTimings;
    bool            mbDesignMode;
    bool            mbIsPaused;
    bool            mbInputFreeze;

    PresentationSettings maPresSettings;

    /// used in updateHdl to prevent recursive calls
    sal_Int32       mnEntryCounter;

    sal_Int32       mnLastSlideNumber;
    WrappedShapeEventImplMap    maShapeEventMap;

    ::rtl::OUString msOnClick;
    ::rtl::OUString msBookmark;
    ::rtl::OUString msVerb;

    ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > mxPreviewDrawPage;
    ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode > mxPreviewAnimationNode;

    ::com::sun::star::uno::Reference< ::com::sun::star::media::XPlayer > mxPlayer;
    ::com::sun::star::uno::Reference< ::com::sun::star::media::XManager > mxManager;

    ::std::auto_ptr<PaneHider> mpPaneHider;

    ULONG   mnEndShowEvent;
};

class SlideShowImplGuard
{
public:
    SlideShowImplGuard( SlideshowImpl* pImpl );
    ~SlideShowImplGuard();

private:
    SlideshowImpl* mpImpl;
};

bool SlideshowImpl::isInputFreezed() const
{
    return mbInputFreeze;
}

} // namespace ::sd

#endif
<|endoftext|>