SHOGUN  v1.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SGObject.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 2008-2009 Soeren Sonnenburg
8  * Copyright (C) 2008-2009 Fraunhofer Institute FIRST and Max Planck Society
9  */
10 
11 #include <shogun/lib/config.h>
12 #include <shogun/base/SGObject.h>
13 #include <shogun/io/SGIO.h>
14 #include <shogun/base/Parallel.h>
15 #include <shogun/base/init.h>
16 #include <shogun/base/Version.h>
17 #include <shogun/base/Parameter.h>
18 
19 #include <stdlib.h>
20 #include <stdio.h>
21 
22 
23 namespace shogun
24 {
25  class CMath;
26  class Parallel;
27  class IO;
28  class Version;
29 
30  extern CMath* sg_math;
31  extern Parallel* sg_parallel;
32  extern SGIO* sg_io;
33  extern Version* sg_version;
34 
35  template<> void CSGObject::set_generic<bool>()
36  {
37  m_generic = PT_BOOL;
38  }
39 
40  template<> void CSGObject::set_generic<char>()
41  {
42  m_generic = PT_CHAR;
43  }
44 
45  template<> void CSGObject::set_generic<int8_t>()
46  {
47  m_generic = PT_INT8;
48  }
49 
50  template<> void CSGObject::set_generic<uint8_t>()
51  {
52  m_generic = PT_UINT8;
53  }
54 
55  template<> void CSGObject::set_generic<int16_t>()
56  {
57  m_generic = PT_INT16;
58  }
59 
60  template<> void CSGObject::set_generic<uint16_t>()
61  {
62  m_generic = PT_UINT16;
63  }
64 
65  template<> void CSGObject::set_generic<int32_t>()
66  {
67  m_generic = PT_INT32;
68  }
69 
70  template<> void CSGObject::set_generic<uint32_t>()
71  {
72  m_generic = PT_UINT32;
73  }
74 
75  template<> void CSGObject::set_generic<int64_t>()
76  {
77  m_generic = PT_INT64;
78  }
79 
80  template<> void CSGObject::set_generic<uint64_t>()
81  {
82  m_generic = PT_UINT64;
83  }
84 
85  template<> void CSGObject::set_generic<float32_t>()
86  {
87  m_generic = PT_FLOAT32;
88  }
89 
90  template<> void CSGObject::set_generic<float64_t>()
91  {
92  m_generic = PT_FLOAT64;
93  }
94 
95  template<> void CSGObject::set_generic<floatmax_t>()
96  {
97  m_generic = PT_FLOATMAX;
98  }
99 
100 } /* namespace shogun */
101 
102 using namespace shogun;
103 
105 {
106  init();
107  set_global_objects();
108 
109  SG_GCDEBUG("SGObject created (%p)\n", this);
110 }
111 
113 :io(orig.io), parallel(orig.parallel), version(orig.version)
114 {
115  init();
116  set_global_objects();
117 }
118 
120 {
121  SG_GCDEBUG("SGObject destroyed (%p)\n", this);
122 
123 #ifdef HAVE_PTHREAD
124  PTHREAD_LOCK_DESTROY(&m_ref_lock);
125 #endif
126  unset_global_objects();
127  delete m_parameters;
129 }
130 
131 #ifdef USE_REFERENCE_COUNTING
132 
133 int32_t CSGObject::ref()
134 {
135 #ifdef HAVE_PTHREAD
136  PTHREAD_LOCK(&m_ref_lock);
137 #endif //HAVE_PTHREAD
138  ++m_refcount;
139  int32_t count=m_refcount;
140 #ifdef HAVE_PTHREAD
141  PTHREAD_UNLOCK(&m_ref_lock);
142 #endif //HAVE_PTHREAD
143  SG_GCDEBUG("ref() refcount %ld obj %s (%p) increased\n", count, this->get_name(), this);
144  return m_refcount;
145 }
146 
147 int32_t CSGObject::ref_count()
148 {
149 #ifdef HAVE_PTHREAD
150  PTHREAD_LOCK(&m_ref_lock);
151 #endif //HAVE_PTHREAD
152  int32_t count=m_refcount;
153 #ifdef HAVE_PTHREAD
154  PTHREAD_UNLOCK(&m_ref_lock);
155 #endif //HAVE_PTHREAD
156  SG_GCDEBUG("ref_count(): refcount %d, obj %s (%p)\n", count, this->get_name(), this);
157  return count;
158 }
159 
160 int32_t CSGObject::unref()
161 {
162 #ifdef HAVE_PTHREAD
163  PTHREAD_LOCK(&m_ref_lock);
164 #endif //HAVE_PTHREAD
165  if (m_refcount==0 || --m_refcount==0)
166  {
167  SG_GCDEBUG("unref() refcount %ld, obj %s (%p) destroying\n", m_refcount, this->get_name(), this);
168 #ifdef HAVE_PTHREAD
169  PTHREAD_UNLOCK(&m_ref_lock);
170 #endif //HAVE_PTHREAD
171  delete this;
172  return 0;
173  }
174  else
175  {
176  SG_GCDEBUG("unref() refcount %ld obj %s (%p) decreased\n", m_refcount, this->get_name(), this);
177 #ifdef HAVE_PTHREAD
178  PTHREAD_UNLOCK(&m_ref_lock);
179 #endif //HAVE_PTHREAD
180  return m_refcount;
181  }
182 }
183 #endif //USE_REFERENCE_COUNTING
184 
185 
186 void CSGObject::set_global_objects()
187 {
188  if (!sg_io || !sg_parallel || !sg_version)
189  {
190  fprintf(stderr, "call init_shogun() before using the library, dying.\n");
191  exit(1);
192  }
193 
194  SG_REF(sg_io);
197 
198  io=sg_io;
201 }
202 
203 void CSGObject::unset_global_objects()
204 {
205  SG_UNREF(version);
207  SG_UNREF(io);
208 }
209 
211 {
212  SG_UNREF(sg_io);
213  sg_io=new_io;
214  SG_REF(sg_io);
215 }
216 
218 {
219  SG_REF(sg_io);
220  return sg_io;
221 }
222 
224 {
226  sg_parallel=new_parallel;
228 }
229 
231 {
233  return sg_parallel;
234 }
235 
237 {
239  sg_version=new_version;
241 }
242 
244 {
246  return sg_version;
247 }
248 
249 bool CSGObject::is_generic(EPrimitiveType* generic) const
250 {
251  *generic = m_generic;
252 
253  return m_generic != PT_NOT_GENERIC;
254 }
255 
257 {
258  m_generic = PT_NOT_GENERIC;
259 }
260 
261 void CSGObject::print_serializable(const char* prefix)
262 {
263  SG_PRINT("\n%s\n================================================================================\n", get_name());
264  m_parameters->print(prefix);
265 }
266 
268  const char* prefix)
269 {
270  SG_DEBUG("START SAVING CSGObject '%s'\n", get_name());
271  try
272  {
274  }
275  catch (ShogunException e)
276  {
277  SG_SWARNING("%s%s::save_serializable_pre(): ShogunException: "
278  "%s\n", prefix, get_name(),
280  return false;
281  }
282  if (!m_save_pre_called)
283  {
284  SG_SWARNING("%s%s::save_serializable_pre(): Implementation "
285  "error: BASE_CLASS::LOAD_SERIALIZABLE_PRE() not "
286  "called!\n", prefix, get_name());
287  return false;
288  }
289 
290  /* save parameter version */
291  if (!save_parameter_version(file, prefix))
292  return false;
293 
294  if (!m_parameters->save(file, prefix))
295  return false;
296 
297  try
298  {
300  }
301  catch (ShogunException e)
302  {
303  SG_SWARNING("%s%s::save_serializable_post(): ShogunException: "
304  "%s\n", prefix, get_name(),
306  return false;
307  }
308 
309  if (!m_save_post_called)
310  {
311  SG_SWARNING("%s%s::save_serializable_post(): Implementation "
312  "error: BASE_CLASS::LOAD_SERIALIZABLE_POST() not "
313  "called!\n", prefix, get_name());
314  return false;
315  }
316 
317  if (prefix == NULL || *prefix == '\0')
318  file->close();
319 
320  SG_DEBUG("DONE SAVING CSGObject '%s' (%p)\n", get_name(), this);
321 
322  return true;;
323 }
324 
326  const char* prefix)
327 {
328  SG_DEBUG("START LOADING CSGObject '%s'\n", get_name());
329  try
330  {
332  }
333  catch (ShogunException e)
334  {
335  SG_SWARNING("%s%s::load_serializable_pre(): ShogunException: "
336  "%s\n", prefix, get_name(),
338  return false;
339  }
340  if (!m_load_pre_called)
341  {
342  SG_SWARNING("%s%s::load_serializable_pre(): Implementation "
343  "error: BASE_CLASS::LOAD_SERIALIZABLE_PRE() not "
344  "called!\n", prefix, get_name());
345  return false;
346  }
347 
348  /* try to load version of parameters */
349  int32_t file_version=load_parameter_version(file, prefix);
350 
351  if (file_version<0)
352  {
353  SG_WARNING("%s%s::load_serializable(): File contains no parameter "
354  "version. Seems like your file is from the days before this "
355  "was introduced. Ignore warning or serialize with this version "
356  "of shogun to get rid of above and this warnings.\n",
357  prefix, get_name());
358  }
359 
360  if (file_version>version->get_version_parameter())
361  {
362  SG_WARNING("%s%s::load_serializable(): parameter version of file "
363  "larger than the one of shogun. Try with a more recent version "
364  "of shogun.\n", prefix, get_name());
365  return false;
366  }
367 
368  if (!m_parameters->load(file, prefix))
369  return false;
370 
371  try
372  {
374  }
375  catch (ShogunException e)
376  {
377  SG_SWARNING("%s%s::load_serializable_post(): ShogunException: "
378  "%s\n", prefix, get_name(),
380  return false;
381  }
382 
383  if (!m_load_post_called)
384  {
385  SG_SWARNING("%s%s::load_serializable_post(): Implementation "
386  "error: BASE_CLASS::LOAD_SERIALIZABLE_POST() not "
387  "called!\n", prefix, get_name());
388  return false;
389  }
390  SG_DEBUG("DONE LOADING CSGObject '%s' (%p)\n", get_name(), this);
391 
392  return true;
393 }
394 
395 bool CSGObject::save_parameter_version(CSerializableFile* file,
396  const char* prefix)
397 {
398  TSGDataType t(CT_SCALAR, ST_NONE, PT_INT32);
399  int32_t v=version->get_version_parameter();
400  TParameter p(&t, &v, "version_parameter",
401  "Version of parameters of this object");
402  return p.save(file, prefix);
403 }
404 
405 int32_t CSGObject::load_parameter_version(CSerializableFile* file,
406  const char* prefix)
407 {
408  TSGDataType t(CT_SCALAR, ST_NONE, PT_INT32);
409  int32_t v;
410  TParameter tp(&t, &v, "version_parameter", "");
411  if (tp.load(file, prefix))
412  return v;
413  else
414  return -1;
415 }
416 
418 {
419  m_load_pre_called = true;
420 }
421 
423 {
424  m_load_post_called = true;
425 }
426 
428 {
429  m_save_pre_called = true;
430 }
431 
433 {
434  m_save_post_called = true;
435 }
436 
437 #ifdef TRACE_MEMORY_ALLOCS
438 #include <shogun/lib/Set.h>
439 extern CSet<shogun::MemoryBlock>* sg_mallocs;
440 #endif
441 
442 void CSGObject::init()
443 {
444 #ifdef HAVE_PTHREAD
445  PTHREAD_LOCK_INIT(&m_ref_lock);
446 #endif
447 
448 #ifdef TRACE_MEMORY_ALLOCS
449  if (sg_mallocs)
450  {
451  int32_t idx=sg_mallocs->index_of(MemoryBlock(this));
452  if (idx>-1)
453  {
454  MemoryBlock* b=sg_mallocs->get_element_ptr(idx);
455  b->set_sgobject();
456  }
457  }
458 #endif
459 
460  m_refcount = 0;
461  io = NULL;
462  parallel = NULL;
463  version = NULL;
464  m_parameters = new Parameter();
466  m_generic = PT_NOT_GENERIC;
467  m_load_pre_called = false;
468  m_load_post_called = false;
469 }
470 
472 {
475 
476  for (index_t i=0; i<result.vlen; ++i)
478 
479  return result;
480 }
481 
482 char* CSGObject::get_modsel_param_descr(const char* param_name)
483 {
484  index_t index=get_modsel_param_index(param_name);
485 
486  if (index<0)
487  {
488  SG_ERROR("There is no model selection parameter called \"%s\" for %s",
489  param_name, get_name());
490  }
491 
493 }
494 
496 {
497  /* use fact that names extracted from below method are in same order than
498  * in m_model_selection_parameters variable */
500 
501  /* search for parameter with provided name */
502  index_t index=-1;
503  for (index_t i=0; i<names.vlen; ++i)
504  {
506  if (!strcmp(param_name, current->m_name))
507  {
508  index=i;
509  break;
510  }
511  }
512 
513  /* clean up */
514  names.destroy_vector();
515 
516  return index;
517 }

SHOGUN Machine Learning Toolbox - Documentation