<commit_before>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium 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 Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __BH_JITK_BASE_DB_H
#define __BH_JITK_BASE_DB_H

#include <map>
#include <vector>
#include <string>
#include <sstream>

#include <bh_view.hpp>
#include <bh_util.hpp>
#include <bh_config_parser.hpp>

#include <jitk/block.hpp>

namespace bohrium {
namespace jitk {

// Compare class for the index sets and maps
struct idx_less {
    // This compare is the same as view compare ('v1 < v2') but ignoring their bases
    bool operator() (const bh_view& v1, const bh_view& v2) const {
        if (v1.start < v2.start) return true;
        if (v2.start < v1.start) return false;
        if (v1.ndim < v2.ndim) return true;
        if (v2.ndim < v1.ndim) return false;
        for (bh_intp i = 0; i < v1.ndim; ++i) {
            if (v1.shape[i] < v2.shape[i]) return true;
            if (v2.shape[i] < v1.shape[i]) return false;
        }
        for (bh_intp i = 0; i < v1.ndim; ++i) {
            if (v1.stride[i] < v2.stride[i]) return true;
            if (v2.stride[i] < v1.stride[i]) return false;
        }
        return false;
    }
};

// Compare class for the OffsetAndStrides sets and maps
struct OffsetAndStrides_less {
    // This compare is the same as view compare ('v1 < v2') but ignoring their bases
    bool operator() (const bh_view& v1, const bh_view& v2) const {
        if (v1.ndim < v2.ndim) return true;
        if (v2.ndim < v1.ndim) return false;
        if (v1.start < v2.start) return true;
        if (v2.start < v1.start) return false;
        for (bh_intp i = 0; i < v1.ndim; ++i) {
            if (v1.stride[i] < v2.stride[i]) return true;
            if (v2.stride[i] < v1.stride[i]) return false;
        }
        return false;
    }
    bool operator() (const bh_view* v1, const bh_view* v2) const {
        return (*this)(*v1, *v2);
    }
};

class SymbolTable {
private:
    std::map<bh_base*, size_t> _base_map; // Mapping a base to its ID
    std::map<bh_view, size_t> _view_map; // Mapping a view to its ID
    std::map<bh_view, size_t, idx_less> _idx_map; // Mapping a index (of an array) to its ID
    std::map<bh_view, size_t, OffsetAndStrides_less> _offset_strides_map; // Mapping a offset-and-strides to its ID

public:
    SymbolTable(const std::vector<InstrPtr> &instr_list) {
        // NB: by assigning the IDs in the order they appear in the 'instr_list',
        //     the kernels can better be reused
        for (const InstrPtr instr: instr_list) {
            for (const bh_view *view: instr->get_views()) {
                _base_map.insert(std::make_pair(view->base, _base_map.size()));
                _view_map.insert(std::make_pair(*view, _view_map.size()));
                _idx_map.insert(std::make_pair(*view, _idx_map.size()));
                _offset_strides_map.insert(std::make_pair(*view, _offset_strides_map.size()));
            }
        }
    };
    // Get the ID of 'base', throws exception if 'base' doesn't exist
    size_t baseID(bh_base *base) const {
        return _base_map.at(base);
    }
    // Get the ID of 'view', throws exception if 'view' doesn't exist
    size_t viewID(const bh_view &view) const {
        return _view_map.at(view);
    }
    // Get the ID of 'index', throws exception if 'index' doesn't exist
    size_t idxID(const bh_view &index) const {
        return _idx_map.at(index);
    }
    // Check if 'index' exist
    size_t existIdxID(const bh_view &index) const {
        return util::exist(_idx_map, index);
    }
    // Get the offset-and-strides ID of 'view', throws exception if 'view' doesn't exist
    size_t offsetStridesID(const bh_view &view) const {
        return _offset_strides_map.at(view);
    }
    size_t existOffsetStridesID(const bh_view &view) const {
        return util::exist(_offset_strides_map,view);
    }
};

class Scope {
public:
    const SymbolTable &symbols;
    const Scope * const parent;
private:
    std::set<bh_base*> _tmps; // Set of temporary arrays
    std::set<bh_base*> _scalar_replacements_rw; // Set of scalar replaced arrays that both reads and writes
    std::set<bh_view> _scalar_replacements_r; // Set of scalar replaced arrays
    std::set<bh_view> _omp_atomic; // Set of arrays that should be guarded by OpenMP atomic
    std::set<bh_view> _omp_critical; // Set of arrays that should be guarded by OpenMP critical
    std::set<bh_base*> _declared_base; // Set of bases that have been locally declared (e.g. a temporary variable)
    std::set<bh_view> _declared_view; // Set of views that have been locally declared (e.g. a temporary variable)
    std::set<bh_view, idx_less> _declared_idx; // Set of indexes that have been locally declared
public:
    // Should we declare scalar variables using the volatile keyword?
    const bool use_volatile;<commit_msg>Implemented SymbolTable::constID()<commit_after>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium 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 Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __BH_JITK_BASE_DB_H
#define __BH_JITK_BASE_DB_H

#include <map>
#include <vector>
#include <string>
#include <sstream>

#include <bh_view.hpp>
#include <bh_util.hpp>
#include <bh_config_parser.hpp>

#include <jitk/block.hpp>

namespace bohrium {
namespace jitk {

// Compare class for the index sets and maps
struct idx_less {
    // This compare is the same as view compare ('v1 < v2') but ignoring their bases
    bool operator() (const bh_view& v1, const bh_view& v2) const {
        if (v1.start < v2.start) return true;
        if (v2.start < v1.start) return false;
        if (v1.ndim < v2.ndim) return true;
        if (v2.ndim < v1.ndim) return false;
        for (bh_intp i = 0; i < v1.ndim; ++i) {
            if (v1.shape[i] < v2.shape[i]) return true;
            if (v2.shape[i] < v1.shape[i]) return false;
        }
        for (bh_intp i = 0; i < v1.ndim; ++i) {
            if (v1.stride[i] < v2.stride[i]) return true;
            if (v2.stride[i] < v1.stride[i]) return false;
        }
        return false;
    }
};

// Compare class for the OffsetAndStrides sets and maps
struct OffsetAndStrides_less {
    // This compare is the same as view compare ('v1 < v2') but ignoring their bases
    bool operator() (const bh_view& v1, const bh_view& v2) const {
        if (v1.ndim < v2.ndim) return true;
        if (v2.ndim < v1.ndim) return false;
        if (v1.start < v2.start) return true;
        if (v2.start < v1.start) return false;
        for (bh_intp i = 0; i < v1.ndim; ++i) {
            if (v1.stride[i] < v2.stride[i]) return true;
            if (v2.stride[i] < v1.stride[i]) return false;
        }
        return false;
    }
    bool operator() (const bh_view* v1, const bh_view* v2) const {
        return (*this)(*v1, *v2);
    }
};

// Compare class for the constant_map
struct Constant_less {
    // This compare tje 'origin_id' member of the instructions
    bool operator() (const InstrPtr &i1, const InstrPtr& i2) const {
        return i1->origin_id < i2->origin_id;
    }
};

class SymbolTable {
private:
    std::map<bh_base*, size_t> _base_map; // Mapping a base to its ID
    std::map<bh_view, size_t> _view_map; // Mapping a view to its ID
    std::map<bh_view, size_t, idx_less> _idx_map; // Mapping a index (of an array) to its ID
    std::map<bh_view, size_t, OffsetAndStrides_less> _offset_strides_map; // Mapping a offset-and-strides to its ID
    std::set<InstrPtr, Constant_less> _constant_set; // Sets of instructions to a constant ID

public:
    SymbolTable(const std::vector<InstrPtr> &instr_list) {
        // NB: by assigning the IDs in the order they appear in the 'instr_list',
        //     the kernels can better be reused
        for (const InstrPtr &instr: instr_list) {
            for (const bh_view *view: instr->get_views()) {
                _base_map.insert(std::make_pair(view->base, _base_map.size()));
                _view_map.insert(std::make_pair(*view, _view_map.size()));
                _idx_map.insert(std::make_pair(*view, _idx_map.size()));
                _offset_strides_map.insert(std::make_pair(*view, _offset_strides_map.size()));
            }
            assert(instr->origin_id >= 0);
            if (instr->has_constant() and bh_opcode_is_elementwise(instr->opcode) and instr->opcode != BH_RANDOM) {
                _constant_set.insert(instr);
            }
        }
    };
    // Get the ID of 'base', throws exception if 'base' doesn't exist
    size_t baseID(bh_base *base) const {
        return _base_map.at(base);
    }
    // Get the ID of 'view', throws exception if 'view' doesn't exist
    size_t viewID(const bh_view &view) const {
        return _view_map.at(view);
    }
    // Get the ID of 'index', throws exception if 'index' doesn't exist
    size_t idxID(const bh_view &index) const {
        return _idx_map.at(index);
    }
    // Check if 'index' exist
    bool existIdxID(const bh_view &index) const {
        return util::exist(_idx_map, index);
    }
    // Get the offset-and-strides ID of 'view', throws exception if 'view' doesn't exist
    size_t offsetStridesID(const bh_view &view) const {
        return _offset_strides_map.at(view);
    }
    bool existOffsetStridesID(const bh_view &view) const {
        return util::exist(_offset_strides_map,view);
    }
    // Get the ID of the constant within 'instr', which is simply 'instr.origin_id'
    size_t constID(const bh_instruction &instr) const {
        assert(instr.origin_id >= 0);
        return instr.origin_id;
    }
    const std::set<InstrPtr, Constant_less> &constIDs() const {
        return _constant_set;
    };
};

class Scope {
public:
    const SymbolTable &symbols;
    const Scope * const parent;
private:
    std::set<bh_base*> _tmps; // Set of temporary arrays
    std::set<bh_base*> _scalar_replacements_rw; // Set of scalar replaced arrays that both reads and writes
    std::set<bh_view> _scalar_replacements_r; // Set of scalar replaced arrays
    std::set<bh_view> _omp_atomic; // Set of arrays that should be guarded by OpenMP atomic
    std::set<bh_view> _omp_critical; // Set of arrays that should be guarded by OpenMP critical
    std::set<bh_base*> _declared_base; // Set of bases that have been locally declared (e.g. a temporary variable)
    std::set<bh_view> _declared_view; // Set of views that have been locally declared (e.g. a temporary variable)
    std::set<bh_view, idx_less> _declared_idx; // Set of indexes that have been locally declared
public:
    // Should we declare scalar variables using the volatile keyword?
    const bool use_volatile;
{'fraction_non_alphanumeric': 0.10704584040747028, 'fraction_numerical': 0.00967741935483871, 'mean_word_length': 2.9454119223040856, 'pattern_counts': {'":': 0, '<': 90, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6166785', 'n_tokens_mistral': 3915, 'n_tokens_neox': 3827, 'n_words': 1271}