1 // Copyright(C) 1999-2020 National Technology & Engineering Solutions
2 // of Sandia, LLC (NTESS).  Under the terms of Contract DE-NA0003525 with
3 // NTESS, the U.S. Government retains certain rights in this software.
4 //
5 // See packages/seacas/LICENSE for details
6 
7 #ifndef IOSS_Ioss_Map_h
8 #define IOSS_Ioss_Map_h
9 
10 #include "vtk_ioss_mangle.h"
11 
12 #include <Ioss_CodeTypes.h>
13 #include <cstddef> // for size_t
14 #include <cstdint> // for int64_t
15 #include <string>  // for string
16 #include <vector>  // for vector
17 
18 #define MAP_USE_HOPSCOTCH
19 #if defined MAP_USE_STD
20 #include <unordered_map>
21 #elif defined MAP_USE_HOPSCOTCH
22 #include <bhopscotch_map.h>
23 #elif defined MAP_USE_ROBIN
24 #include <robin_map.h>
25 #endif
26 
27 namespace Ioss {
28   class Field;
29 } // namespace Ioss
30 
31 namespace Ioss {
32 
33   using MapContainer = std::vector<int64_t>;
34 #if defined MAP_USE_STD
35   using ReverseMapContainer = std::unordered_map<int64_t, int64_t>;
36 #elif defined MAP_USE_HOPSCOTCH
37   // The `b` variant requires less-than-comparable key, but is faster
38   using ReverseMapContainer = tsl::bhopscotch_map<int64_t, int64_t>;
39   // using ReverseMapContainer = tsl::hopscotch_map<int64_t, int64_t>;
40   // using ReverseMapContainer = tsl::hopscotch_pg_map<int64_t, int64_t>;
41 #elif defined MAP_USE_ROBIN
42   using ReverseMapContainer = tsl::robin_map<int64_t, int64_t>;
43   // using ReverseMapContainer = tsl::robin_pg_map<int64_t, int64_t>;
44 #endif
45 
46   class Map
47   {
48   public:
49     Map() = default;
Map(std::string entity_type,std::string file_name,int processor)50     Map(std::string entity_type, std::string file_name, int processor)
51         : m_entityType(std::move(entity_type)), m_filename(std::move(file_name)),
52           m_myProcessor(processor)
53     {
54     }
55     Map(const Map &from) = delete;
56     Map &operator=(const Map &from) = delete;
57     ~Map()                          = default;
58 
59     void   set_size(size_t entity_count);
size()60     size_t size() const { return m_map.empty() ? 0 : m_map.size() - 1; }
61 
set_is_sequential(bool yesno)62     void set_is_sequential(bool yesno) { m_map[0] = yesno ? -1 : 1; }
63 
64     // Determines whether the input map is sequential (m_map[i] == i)
65     bool is_sequential(bool check_all = false) const;
66 
67     int64_t global_to_local(int64_t global, bool must_exist = true) const;
68 
69     template <typename INT>
70     bool set_map(INT *ids, size_t count, size_t offset, bool in_define_mode = true);
71 
72     void set_default(size_t count, size_t offset = 0);
73 
74     void build_reverse_map();
75     void build_reverse_map_no_lock();
76     void build_reverse_map(int64_t num_to_get, int64_t offset);
77 
78     void release_memory(); //! Release memory for all maps.
79 
80     void reverse_map_data(void *data, const Ioss::Field &field, size_t count) const;
81     void map_data(void *data, const Ioss::Field &field, size_t count) const;
82     void map_implicit_data(void *data, const Ioss::Field &field, size_t count, size_t offset) const;
83 
84     template <typename T>
85     size_t map_field_to_db_scalar_order(T *variables, std::vector<double> &db_var,
86                                         size_t begin_offset, size_t count, size_t stride,
87                                         size_t offset);
88 
map()89     const MapContainer &map() const { return m_map; }
map()90     MapContainer &      map() { return m_map; }
91 
defined()92     bool defined() const { return m_defined; }
set_defined(bool yes_no)93     void set_defined(bool yes_no) { m_defined = yes_no; }
94 
reorders()95     bool reorders() const { return !m_reorder.empty(); }
96 
97   private:
98     template <typename INT> void reverse_map_data(INT *data, size_t count) const;
99     template <typename INT> void map_data(INT *data, size_t count) const;
100     template <typename INT> void map_implicit_data(INT *data, size_t count, size_t offset) const;
101 
102     int64_t global_to_local__(int64_t global, bool must_exist = true) const;
103     void    build_reorder_map__(int64_t start, int64_t count);
104     void    build_reverse_map__(int64_t num_to_get, int64_t offset);
105 
106 #if defined(IOSS_THREADSAFE)
107     mutable std::mutex m_;
108 #endif
109     MapContainer        m_map{};
110     MapContainer        m_reorder{};
111     ReverseMapContainer m_reverse{};
112     std::string         m_entityType{"unknown"}; // node, element, edge, face
113     std::string         m_filename{"undefined"}; // For error messages only.
114     int64_t             m_offset{-1};            // local to global offset if m_map is sequential.
115     int                 m_myProcessor{0};        // For error messages...
116     bool m_defined{false}; // For use by some clients; not all, so don't read too much into value...
117   };
118 } // namespace Ioss
119 
120 #endif // IOSS_Ioss_Map_h
121