19
19
#include " atlas/runtime/Log.h"
20
20
#include " atlas/trans/Trans.h"
21
21
22
- // For factory registration only:
23
- #if ATLAS_HAVE_TRANS
24
- #include " atlas/trans/ifs/TransIFSNodeColumns.h"
25
- #include " atlas/trans/ifs/TransIFSStructuredColumns.h"
26
- #endif
27
- #include " atlas/trans/local/TransLocal.h" // --> recommended "local"
28
-
29
22
namespace {
30
23
struct default_backend {
31
24
#if ATLAS_HAVE_TRANS
@@ -46,41 +39,37 @@ struct default_backend {
46
39
namespace atlas {
47
40
namespace trans {
48
41
49
- util::Config TransFactory::default_options_ = util::Config( " type" , default_backend::instance().value );
42
+
43
+ class TransBackend {
44
+ public:
45
+ static void list ( std::ostream& );
46
+ static bool has ( const std::string& name );
47
+ static void backend ( const std::string& );
48
+ static std::string backend ();
49
+ static void config ( const eckit::Configuration& );
50
+ static const eckit::Configuration& config ();
51
+
52
+ private:
53
+ static util::Config default_options_;
54
+ };
55
+
56
+ util::Config TransBackend::default_options_ = util::Config( " type" , default_backend::instance().value );
50
57
51
58
TransImpl::~TransImpl () {}
52
59
53
60
namespace {
54
61
55
62
static eckit::Mutex* local_mutex = 0 ;
63
+ static std::map<std::string, int >* b = 0 ;
56
64
static std::map<std::string, TransFactory*>* m = 0 ;
57
65
static pthread_once_t once = PTHREAD_ONCE_INIT;
58
66
59
67
static void init () {
60
68
local_mutex = new eckit::Mutex ();
69
+ b = new std::map<std::string, int >();
61
70
m = new std::map<std::string, TransFactory*>();
62
71
}
63
72
64
- template <typename T>
65
- void load_builder_functionspace () {
66
- TransBuilderFunctionSpace<T>( " tmp" );
67
- }
68
- template <typename T>
69
- void load_builder_grid () {
70
- TransBuilderGrid<T>( " tmp" );
71
- }
72
-
73
- struct force_link {
74
- force_link () {
75
- #if ATLAS_HAVE_TRANS
76
- load_builder_functionspace<TransIFSNodeColumns>();
77
- load_builder_functionspace<TransIFSStructuredColumns>();
78
- load_builder_grid<TransIFS>();
79
- #endif
80
- load_builder_grid<TransLocal>();
81
- }
82
- };
83
-
84
73
TransFactory& factory ( const std::string& name ) {
85
74
std::map<std::string, TransFactory*>::const_iterator j = m->find ( name );
86
75
if ( j == m->end () ) {
@@ -95,64 +84,71 @@ TransFactory& factory( const std::string& name ) {
95
84
96
85
} // namespace
97
86
98
- TransFactory::TransFactory ( const std::string& name ) : name_( name ) {
87
+ TransFactory::TransFactory ( const std::string& name, const std::string& backend ) : name_( name ), backend_( backend ) {
99
88
pthread_once ( &once, init );
100
89
101
90
eckit::AutoLock<eckit::Mutex> lock ( local_mutex );
102
91
103
92
ASSERT ( m->find ( name ) == m->end () );
104
93
( *m )[name] = this ;
94
+
95
+ if ( b->find ( backend ) == b->end () ) ( *b )[backend] = 0 ;
96
+ ( *b )[backend]++;
105
97
}
106
98
107
99
TransFactory::~TransFactory () {
108
100
eckit::AutoLock<eckit::Mutex> lock ( local_mutex );
109
101
m->erase ( name_ );
102
+ ( *b )[backend_]--;
103
+ if ( ( *b )[backend_] == 0 ) b->erase ( backend_ );
110
104
}
111
105
112
106
bool TransFactory::has ( const std::string& name ) {
113
107
pthread_once ( &once, init );
114
-
115
108
eckit::AutoLock<eckit::Mutex> lock ( local_mutex );
116
-
117
- static force_link static_linking;
118
-
119
109
return ( m->find ( name ) != m->end () );
120
110
}
121
111
122
- void TransFactory::backend ( const std::string& backend ) {
112
+ bool TransBackend::has ( const std::string& name ) {
113
+ pthread_once ( &once, init );
114
+ eckit::AutoLock<eckit::Mutex> lock ( local_mutex );
115
+ return ( b->find ( name ) != b->end () );
116
+ }
117
+
118
+ void TransBackend::backend ( const std::string& backend ) {
123
119
pthread_once ( &once, init );
124
120
eckit::AutoLock<eckit::Mutex> lock ( local_mutex );
125
121
default_options_.set ( " type" , backend );
126
122
}
127
123
128
- std::string TransFactory ::backend () {
124
+ std::string TransBackend ::backend () {
129
125
return default_options_.getString ( " type" );
130
126
}
131
127
132
- const eckit::Configuration& TransFactory ::config () {
128
+ const eckit::Configuration& TransBackend ::config () {
133
129
return default_options_;
134
130
}
135
131
136
- void TransFactory ::config ( const eckit::Configuration& config ) {
132
+ void TransBackend ::config ( const eckit::Configuration& config ) {
137
133
std::string type = default_options_.getString ( " type" );
138
134
default_options_ = config;
139
135
if ( not config.has ( " type" ) ) { default_options_.set ( " type" , type ); }
140
136
}
141
137
142
- void TransFactory ::list ( std::ostream& out ) {
138
+ void TransBackend ::list ( std::ostream& out ) {
143
139
pthread_once ( &once, init );
144
-
145
140
eckit::AutoLock<eckit::Mutex> lock ( local_mutex );
146
-
147
- static force_link static_linking;
148
-
149
141
const char * sep = " " ;
150
- for ( std::map<std::string, TransFactory* >::const_iterator j = m ->begin (); j != m ->end (); ++j ) {
142
+ for ( std::map<std::string, int >::const_iterator j = b ->begin (); j != b ->end (); ++j ) {
151
143
out << sep << ( *j ).first ;
152
144
sep = " , " ;
153
145
}
154
146
}
155
147
148
+ void TransFactory::list ( std::ostream& out ) {
149
+ TransBackend::list ( out );
150
+ }
151
+
156
152
Trans::Implementation* TransFactory::build ( const FunctionSpace& gp, const FunctionSpace& sp,
157
153
const eckit::Configuration& config ) {
158
154
return build ( Cache (), gp, sp, config );
@@ -169,13 +165,22 @@ Trans::Implementation* TransFactory::build( const Cache& cache, const FunctionSp
169
165
170
166
eckit::AutoLock<eckit::Mutex> lock ( local_mutex );
171
167
172
- static force_link static_linking;
173
-
174
- util::Config options = default_options_;
168
+ util::Config options = TransBackend::config ();
175
169
options.set ( config );
176
170
171
+ std::string backend = options.getString ( " type" );
172
+
173
+ Log::debug () << " Looking for TransFactory [" << backend << " ]" << std::endl;
174
+ if ( !TransBackend::has ( backend ) ) {
175
+ Log::error () << " No TransFactory for [" << backend << " ]" << std::endl;
176
+ Log::error () << " TransFactories are :" << std::endl;
177
+ TransBackend::list ( Log::error () );
178
+ Log::error () << std::endl;
179
+ throw eckit::SeriousBug ( std::string ( " No TransFactory called " ) + backend );
180
+ }
181
+
177
182
std::string suffix ( " (" + gp.type () + " ," + sp.type () + " )" );
178
- std::string name = options. getString ( " type " ) + suffix;
183
+ std::string name = backend + suffix;
179
184
180
185
Log::debug () << " Looking for TransFactory [" << name << " ]" << std::endl;
181
186
@@ -207,37 +212,44 @@ Trans::Implementation* TransFactory::build( const Cache& cache, const Grid& grid
207
212
208
213
eckit::AutoLock<eckit::Mutex> lock ( local_mutex );
209
214
210
- static force_link static_linking;
211
-
212
- util::Config options = default_options_;
215
+ util::Config options = TransBackend::config ();
213
216
options.set ( config );
214
217
215
- std::string name = options.getString ( " type" );
218
+ std::string backend = options.getString ( " type" );
216
219
217
- Log::debug () << " Looking for TransFactory [" << name << " ]" << std::endl;
220
+ Log::debug () << " Looking for TransFactory [" << backend << " ]" << std::endl;
221
+ if ( !TransBackend::has ( backend ) ) {
222
+ Log::error () << " No TransFactory for [" << backend << " ]" << std::endl;
223
+ Log::error () << " TransFactories are :" << std::endl;
224
+ TransBackend::list ( Log::error () );
225
+ Log::error () << std::endl;
226
+ throw eckit::SeriousBug ( std::string ( " No TransFactory called " ) + backend );
227
+ }
228
+
229
+ std::string name = backend;
218
230
219
231
return factory ( name ).make ( cache, grid, domain, truncation, options );
220
232
}
221
233
222
234
bool Trans::hasBackend ( const std::string& backend ) {
223
- return TransFactory ::has ( backend );
235
+ return TransBackend ::has ( backend );
224
236
}
225
237
226
238
void Trans::backend ( const std::string& backend ) {
227
239
ASSERT ( hasBackend ( backend ) );
228
- TransFactory ::backend ( backend );
240
+ TransBackend ::backend ( backend );
229
241
}
230
242
231
243
std::string Trans::backend () {
232
- return TransFactory ::backend ();
244
+ return TransBackend ::backend ();
233
245
}
234
246
235
247
const eckit::Configuration& Trans::config () {
236
- return TransFactory ::config ();
248
+ return TransBackend ::config ();
237
249
}
238
250
239
251
void Trans::config ( const eckit::Configuration& options ) {
240
- TransFactory ::config ( options );
252
+ TransBackend ::config ( options );
241
253
}
242
254
243
255
namespace {
0 commit comments