Skip to content

Commit

Permalink
Merge pull request bhmm#48 from marscher/malloc_check
Browse files Browse the repository at this point in the history
check for malloc failures and gracefully handle them
  • Loading branch information
marscher authored Dec 13, 2017
2 parents da0a53e + a8c4dde commit 0585781
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 42 deletions.
18 changes: 9 additions & 9 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,29 @@ environment:
matrix:
- PYTHON: "C:\\Miniconda"
CONDA_PY: "27"
CONDA_NPY: "19"
CONDA_NPY: "110"

- PYTHON: "C:\\Miniconda-x64"
CONDA_PY: "27"
CONDA_NPY: "19"
CONDA_NPY: "112"
ARCH: "64"

- PYTHON: "C:\\Miniconda3"
CONDA_PY: "34"
CONDA_NPY: "19"
CONDA_PY: "35"
CONDA_NPY: "113"

- PYTHON: "C:\\Miniconda3-x64"
CONDA_PY: "34"
CONDA_NPY: "19"
CONDA_PY: "36"
CONDA_NPY: "113"
ARCH: "64"

install:
- set PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%
- conda config --add channels omnia
- conda update -yq --all
- conda install -yq conda-build jinja2
- conda config --add channels conda-forge
- conda install -yq conda-build

build: false

test_script:
- "%CMD_IN_ENV% conda build --quiet devtools\\conda-recipe"

45 changes: 31 additions & 14 deletions bhmm/hidden/impl_c/_hidden.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ void _compute_state_counts(
}*/


void _compute_transition_counts(
int _compute_transition_counts(
double *transition_counts,
const double *A,
const double *pobs,
Expand All @@ -162,6 +162,9 @@ void _compute_transition_counts(
transition_counts[i*N+j] = 0.0;

tmp = (double*) malloc(N*N * sizeof(double));
if (! tmp) {
return _BHMM_ERR_NO_MEM;
}
for (t = 0; t < T-1; t++)
{
sum = 0.0;
Expand All @@ -176,6 +179,7 @@ void _compute_transition_counts(
transition_counts[i*N+j] += tmp[i*N+j] / sum;
}
free(tmp);
return 0;
}


Expand All @@ -196,24 +200,30 @@ int argmax(double* v, int N)
}


void _compute_viterbi(
int _compute_viterbi(
int *path,
const double *A,
const double *pobs,
const double *pi,
int N, int T)
{
int i, j, t, maxi;
double sum, maxprod, p;

int i, j, t, maxi, result;
double sum;
double *v, *vnext, *h, *vh;
int* ptr;
result = 0;
// allocate v
double* v = (double*) malloc(N * sizeof(double));
double* vnext = (double*) malloc(N * sizeof(double));
double* h = (double*) malloc(N * sizeof(double));
double* vh;
v = (double*) malloc(N * sizeof(double));
vnext = (double*) malloc(N * sizeof(double));
h = (double*) malloc(N * sizeof(double));

// allocate ptr
int* ptr = (int*) malloc(T*N * sizeof(int));
ptr = (int*) malloc(T*N * sizeof(int));

if (! v || ! vnext || !h || ! ptr) {
result = _BHMM_ERR_NO_MEM; // indicate no memory
goto error;
}

// initialization of v
sum = 0.0;
Expand Down Expand Up @@ -260,12 +270,14 @@ void _compute_viterbi(
{
path[t] = ptr[(t+1)*N+path[t+1]];
}

error:
// free memory
free(v);
free(vnext);
free(h);
free(ptr);

return result;
}

int _random_choice(const double* p, const int N)
Expand Down Expand Up @@ -307,7 +319,7 @@ void _normalize(double* v, const int N)
}


void _sample_path(
int _sample_path(
int *path,
const double *alpha,
const double *A,
Expand All @@ -316,7 +328,11 @@ void _sample_path(
{
// initialize variables
int i,t;
double* psel = (double*) malloc(N * sizeof(double));
double* psel;
psel = (double*) malloc(N * sizeof(double));
if (! psel) {
return _BHMM_ERR_NO_MEM;
}

// initialize random number generator
srand(time(NULL));
Expand Down Expand Up @@ -353,6 +369,7 @@ void _sample_path(

// free memory
free(psel);
return 0;
}

/*
Expand Down Expand Up @@ -381,4 +398,4 @@ void compute_transition_probabilities(
}
}
}
*/
*/
8 changes: 5 additions & 3 deletions bhmm/hidden/impl_c/_hidden.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef HMM_H_
#define HMM_H_


#define _BHMM_ERR_NO_MEM 2
/*
API FUNCTIONS
*/
Expand Down Expand Up @@ -29,22 +31,22 @@ void _compute_state_counts(
const double *gamma,
int T, int N);

void _compute_transition_counts(
int _compute_transition_counts(
double *transition_counts,
const double *A,
const double *pobs,
const double *alpha,
const double *beta,
int N, int T);

void _compute_viterbi(
int _compute_viterbi(
int *path,
const double *A,
const double *pobs,
const double *pi,
int N, int T);

void _sample_path(
int _sample_path(
int *path,
const double *alpha,
const double *A,
Expand Down
29 changes: 13 additions & 16 deletions bhmm/hidden/impl_c/hidden.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,12 @@ cimport numpy

cdef extern from "_hidden.h":
double _forward(double * alpha, const double *A, const double *pobs, const double *pi, const int N, const int T)

cdef extern from "_hidden.h":
void _backward(double *beta, const double *A, const double *pobs, const int N, const int T)

# cdef extern from "_hmm.h":
# void _computeGamma(double *gamma, const double *alpha, const double *beta, const int T, const int N)
#
cdef extern from "_hidden.h":
void _compute_transition_counts(double *transition_counts, const double *A, const double *pobs, const double *alpha, const double *beta, int N, int T)

cdef extern from "_hidden.h":
void _compute_viterbi(int *path, const double *A, const double *pobs, const double *pi, int N, int T)

cdef extern from "_hidden.h":
void _sample_path(int *path, const double *alpha, const double *A, const double *pobs, const int N, const int T)
int _compute_transition_counts(double *transition_counts, const double *A, const double *pobs, const double *alpha, const double *beta, int N, int T)
int _compute_viterbi(int *path, const double *A, const double *pobs, const double *pi, int N, int T)
int _sample_path(int *path, const double *alpha, const double *A, const double *pobs, const int N, const int T)
int _BHMM_ERR_NO_MEM


def cdef_double_array(n1, n2):
Expand Down Expand Up @@ -155,7 +146,9 @@ def transition_counts(alpha, beta, A, pobs, T = None, out = None, dtype=numpy.fl
palpha = <double*> numpy.PyArray_DATA(alpha)
pbeta = <double*> numpy.PyArray_DATA(beta)
# call
_compute_transition_counts(pC, pA, ppobs, palpha, pbeta, N, T)
res = _compute_transition_counts(pC, pA, ppobs, palpha, pbeta, N, T)
if res == _BHMM_ERR_NO_MEM:
raise MemoryError()
return C
else:
raise TypeError
Expand All @@ -176,7 +169,9 @@ def viterbi(A, pobs, pi, dtype=numpy.float32):
ppobs = <double*> numpy.PyArray_DATA(pobs)
ppi = <double*> numpy.PyArray_DATA(pi)
# call
_compute_viterbi(ppath, pA, ppobs, ppi, N, T)
res = _compute_viterbi(ppath, pA, ppobs, ppi, N, T)
if res == _BHMM_ERR_NO_MEM:
raise MemoryError()
return path
else:
raise TypeError
Expand All @@ -199,7 +194,9 @@ def sample_path(alpha, A, pobs, T = None, dtype=numpy.float32):
pA = <double*> numpy.PyArray_DATA(A)
ppobs = <double*> numpy.PyArray_DATA(pobs)
# call
_sample_path(ppath, palpha, pA, ppobs, N, T)
res = _sample_path(ppath, palpha, pA, ppobs, N, T)
if res == _BHMM_ERR_NO_MEM:
raise MemoryError()
return path
else:
raise TypeError

0 comments on commit 0585781

Please sign in to comment.