Skip to content

Commit

Permalink
Merge pull request #398 from karlnapf/master
Browse files Browse the repository at this point in the history
First bunch of fixes for migration
  • Loading branch information
Soeren Sonnenburg committed Mar 28, 2012
2 parents 355cb51 + 55f3608 commit c69fb70
Show file tree
Hide file tree
Showing 3 changed files with 261 additions and 192 deletions.
157 changes: 83 additions & 74 deletions src/shogun/base/Parameter.cpp
Expand Up @@ -1575,35 +1575,48 @@ TParameter::TParameter(const TSGDataType* datatype, void* parameter,
m_name = strdup(name);
m_description = strdup(description);
m_delete_data=false;
m_was_allocated_from_scratch=false;
}

TParameter::~TParameter()
{
SG_SDEBUG("entering ~TParameter for \"%s\"\n", m_name);
SG_FREE(m_description);
SG_FREE(m_name);

/* possibly delete content, m_parameter variable, and lengths variables */
if (m_delete_data)
/* possibly delete content, m_parameter variable */
if (m_was_allocated_from_scratch)
{
if (m_datatype.m_ctype!=CT_SCALAR)
delete_cont();
SG_SDEBUG("deleting from scratch data\n");

if (m_parameter != NULL)
if (m_delete_data)
{
/* eventually unref sgobject */
if (m_datatype.m_ptype==PT_SGOBJECT)
SG_UNREF(*((CSGObject**)m_parameter));
/* for non-scalar data, delte_cont does the job, rest is handled
* below */
SG_SDEBUG("deleting pure data\n");
if (m_datatype.m_ctype!=CT_SCALAR)
delete_cont();

if (m_datatype.m_ctype==CT_SCALAR && m_datatype.m_ptype==PT_SGOBJECT)
SG_UNREF(*(CSGObject**)m_parameter);
}

/* delete pointer in any case */
/* free pointer/data */
if (m_parameter)
{
SG_SDEBUG("freeing m_parameter pointer/data at %p\n", m_parameter);
SG_FREE(m_parameter);
}

if (m_datatype.m_length_x != NULL)
/* free lengths */
if (m_datatype.m_length_x)
SG_FREE(m_datatype.m_length_x);

if (m_datatype.m_length_y != NULL)
if (m_datatype.m_length_y)
SG_FREE(m_datatype.m_length_y);
}

SG_SDEBUG("leaving ~TParameter\n");
}

char*
Expand Down Expand Up @@ -1640,7 +1653,7 @@ void
TParameter::delete_cont()
{
if (*(void**) m_parameter != NULL) {
index_t old_length = *m_datatype.m_length_y;
index_t old_length = m_datatype.m_length_y ? *m_datatype.m_length_y : 0;
switch (m_datatype.m_ctype) {
case CT_NDARRAY:
SG_SNOTIMPLEMENTED;
Expand All @@ -1649,7 +1662,6 @@ TParameter::delete_cont()
case CT_SCALAR: case CT_VECTOR: case CT_SGVECTOR: break;
}


switch (m_datatype.m_stype) {
case ST_NONE:
switch (m_datatype.m_ptype) {
Expand Down Expand Up @@ -1684,7 +1696,8 @@ TParameter::delete_cont()
*(CSGObject***) m_parameter;
for (index_t i=0; i<old_length; i++)
if (buf[i] != NULL) SG_UNREF(buf[i]);
delete buf;

SG_FREE(buf);
break;
}
break;
Expand Down Expand Up @@ -1779,6 +1792,11 @@ TParameter::delete_cont()
void
TParameter::new_cont(index_t new_len_y, index_t new_len_x)
{
char* s=SG_MALLOC(char, 200);
m_datatype.to_string(s, 200);
SG_SDEBUG("entering TParameter::new_cont(%d, %d) for \"%s\" of type %s\n",
new_len_y, new_len_x, s, m_name ? m_name : "(nil)");
SG_FREE(s);
delete_cont();

index_t new_length = new_len_y*new_len_x;
Expand Down Expand Up @@ -1933,6 +1951,12 @@ TParameter::new_cont(index_t new_len_y, index_t new_len_x)
*m_datatype.sizeof_stype());
break;
} /* switch (m_datatype.m_stype) */

s=SG_MALLOC(char, 200);
m_datatype.to_string(s, 200);
SG_SDEBUG("leaving TParameter::new_cont(%d, %d) for \"%s\" of type %s\n",
new_len_y, new_len_x, s, m_name ? m_name : "(nil)");
SG_FREE(s);
}

bool
Expand Down Expand Up @@ -2576,8 +2600,15 @@ bool TParameter::operator>(const TParameter& other) const
return strcmp(m_name, other.m_name)>0;
}

void TParameter::allocate_data_from_scratch(index_t len_y, index_t len_x)
void TParameter::allocate_data_from_scratch(index_t len_y, index_t len_x,
bool new_cont_call)
{
SG_SDEBUG("entering TParameter::allocate_data_from_scratch(%d,%d) of "
"\"%s\"\n", len_y, len_x, m_name);

/* set flag to delete all this stuff later on */
m_was_allocated_from_scratch=true;

/* length has to be allocated for matrices/vectors */
switch (m_datatype.m_ctype)
{
Expand Down Expand Up @@ -2619,7 +2650,7 @@ void TParameter::allocate_data_from_scratch(index_t len_y, index_t len_x)
else
{
/* for sgobjects, allocate memory for pointer and set to NULL
* * Will be deleted by the TParameter destructor */
* Will be deleted by the TParameter destructor */
m_parameter=SG_MALLOC(CSGObject**, 1);
*((CSGObject**)m_parameter)=NULL;
}
Expand All @@ -2628,26 +2659,36 @@ void TParameter::allocate_data_from_scratch(index_t len_y, index_t len_x)
{
/* allocate pointer for data pointer */
void** data_p=SG_MALLOC(void*, 1);
*data_p=NULL;

/* allocate dummy data at the point the above pointer points to
* will be freed by the delete_cont() method of TParameter.
* This is needed because new_cont/delete_cont cannot handle
* non-existing data. */
*data_p=SG_MALLOC(uint8_t, 1);
* non-existing data. Set to NULL to avoid problems */
if (new_cont_call)
{
*data_p=SG_MALLOC(void**, 1);
**(void***)data_p=NULL;
}

m_parameter=data_p;

/* perform one data allocation. This may be repeated and therefore
* redundant if load() is called afterwards, however, if one wants
* to write directly to the array data after this call, it is
* necessary */
// SG_SPRINT("new_cont call with len_y=%d, len_x=%d\n", len_y, len_x);
new_cont(len_y, len_x);
if (new_cont_call)
new_cont(len_y, len_x);
}

SG_SDEBUG("leaving TParameter::allocate_data_from_scratch(%d,%d) of "
"\"%s\"\n", len_y, len_x, m_name);
}

void TParameter::copy_data(const TParameter* source)
{
SG_SDEBUG("entering TParameter::copy_data for %s\n", m_name);

/* assert that type is equal */
ASSERT(m_datatype.m_ctype==source->m_datatype.m_ctype);
ASSERT(m_datatype.m_stype==source->m_datatype.m_stype);
Expand All @@ -2661,23 +2702,37 @@ void TParameter::copy_data(const TParameter* source)
if (m_datatype.m_ctype==CT_SCALAR && m_datatype.m_ptype!=PT_SGOBJECT)
{
/* just copy value behind pointer */
SG_SDEBUG("Copying scalar data of size %d from %p to %p\n",
m_datatype.get_size(), source->m_parameter, m_parameter);
memcpy(m_parameter, source->m_parameter,
m_datatype.get_size());
}
else
{
/* if this is a sgobject, the old one has to be unrefed
* and the new one to be reded */
/* if this is a sgobject, the old one has to be unrefed */
if (m_datatype.m_ptype==PT_SGOBJECT)
{
SG_UNREF(*((CSGObject**)m_parameter));
SG_REF(*((CSGObject**)source->m_parameter))
if (m_datatype.m_ctype==CT_SCALAR)
{
SG_UNREF(*((CSGObject**)m_parameter));
}
else
{
int32_t length=1;
length*=m_datatype.m_length_x ? *m_datatype.m_length_x : 1;
length*=m_datatype.m_length_y ? *m_datatype.m_length_y : 1;

for (index_t j=0; j<length; ++j)
{
SG_UNREF(((CSGObject**)(m_parameter))[j]);
}
}
}

/* in this case, data is a pointer pointing to the actual
* data, so copy pointer */
*((void**)m_parameter)=
*((void**)source->m_parameter);
* data, so copy pointer if non-NULL*/
SG_SDEBUG("Copying non-scalar pointer %p\n", *((void**)source->m_parameter));
*((void**)m_parameter)=*((void**)source->m_parameter);
}

/* copy lengths */
Expand All @@ -2686,52 +2741,6 @@ void TParameter::copy_data(const TParameter* source)

if (source->m_datatype.m_length_y)
*m_datatype.m_length_y=*source->m_datatype.m_length_y;
}

void TParameter::delete_all_but_data()
{
if (m_datatype.m_ctype==CT_SCALAR)
{
/* if this a sgobject, unref */
if (m_datatype.m_ptype==PT_SGOBJECT)
SG_UNREF(*((CSGObject**)m_parameter));

/* if scalar, delete data directly (no length allocated) */
SG_FREE(m_parameter);
}
else
{
/* the delete data flag cannot be used here because the data
* is used by the instance that was de-serialized, so delete
* lengths and data pointer by hand */

/* delete lengths and data pointer in case of non-scalars */
if (m_datatype.m_ctype!=CT_SCALAR)
{
/* while deleting lengths, remember them to eventually sgunref
* sgobjects later */
int32_t length=1;

if (m_datatype.m_length_x)
{
length*=*m_datatype.m_length_x;
SG_FREE(m_datatype.m_length_x);
}
if (m_datatype.m_length_y)
{
length*=*m_datatype.m_length_y;
SG_FREE(m_datatype.m_length_y);
}

/* eventually unref sg_objects */
if (m_datatype.m_ptype==PT_SGOBJECT)
{
for (index_t i=0; i<length; ++i)
SG_UNREF(*((CSGObject***)m_parameter)[i]);
}

/* now delete data pointer */
SG_FREE(m_parameter);
}
}
SG_SDEBUG("leaving TParameter::copy_data for %s\n", m_name);
}
19 changes: 7 additions & 12 deletions src/shogun/base/Parameter.h
Expand Up @@ -61,8 +61,11 @@ struct TParameter
*
* @param len_y desired y length of the data
* @param len_x desired x length of the data
* @new_cont_call whether new_cont should be called, if false, only scalar
* non-sgobject data will be allocated (needed for migration)
* */
void allocate_data_from_scratch(index_t len_y, index_t len_x);
void allocate_data_from_scratch(index_t len_y, index_t len_x,
bool new_cont_call=true);

/** Given another TParameter instance (with same type, except for lengths)
* all its data is copied to the current one. This means in case of numeric
Expand All @@ -72,17 +75,6 @@ struct TParameter
* @param source source TParameter instance to copy from */
void copy_data(const TParameter* source);

/** Frees everything of this TParameter except for the data.
* Namely, length variables of type, data pointer for non-scalars of
* PT_SGOBJECT scalars.
* If container type is CT_SCALAR and numeric, the data is also deleted.
* SG_OBJECTS are SG_UNREF'ed
* Do not call unless this TParameter instance was created by
* allocate_data_from scratch because some of these variables may lie on
* stack if not. This method is used in parameter version migration
*/
void delete_all_but_data();

/** operator for comparison, (by string m_name) */
bool operator==(const TParameter& other) const;

Expand Down Expand Up @@ -110,6 +102,9 @@ struct TParameter
* default */
bool m_delete_data;

/* TODO */
bool m_was_allocated_from_scratch;

private:
char* new_prefix(const char* s1, const char* s2);
void delete_cont();
Expand Down

0 comments on commit c69fb70

Please sign in to comment.