提交 6469a825 authored 作者: Laurent Dinh's avatar Laurent Dinh

replace as ChoiceFromUniform prop

上级 72823c46
...@@ -242,11 +242,17 @@ class GPUAChoiceFromUniform(GpuKernelBase, Op): ...@@ -242,11 +242,17 @@ class GPUAChoiceFromUniform(GpuKernelBase, Op):
""" """
__props__ = ("odtype",) __props__ = ("odtype", "replace")
def __init__(self, odtype): def __init__(self, odtype, replace=False):
Op.__init__(self) Op.__init__(self)
self.odtype = odtype self.odtype = odtype
self.replace = replace
def __setstate__(self, state):
self.__dict__.update(state)
if "replace" not in state:
self.replace = False
def get_params(self, node): def get_params(self, node):
return node.outputs[0].type.context return node.outputs[0].type.context
...@@ -282,6 +288,7 @@ class GPUAChoiceFromUniform(GpuKernelBase, Op): ...@@ -282,6 +288,7 @@ class GPUAChoiceFromUniform(GpuKernelBase, Op):
return Apply(self, [pvals, unis, as_scalar(n)], [out]) return Apply(self, [pvals, unis, as_scalar(n)], [out])
def gpu_kernels(self, node, name): def gpu_kernels(self, node, name):
replace = int(self.replace)
code = """ code = """
KERNEL void k_multi_warp_multinomial_wor( KERNEL void k_multi_warp_multinomial_wor(
const ga_size nb_multi, const ga_size nb_multi,
...@@ -318,23 +325,29 @@ KERNEL void k_multi_warp_multinomial_wor( ...@@ -318,23 +325,29 @@ KERNEL void k_multi_warp_multinomial_wor(
global_outs[n * outs_col_stride + global_outs[n * outs_col_stride +
c * outs_row_stride] = m; c * outs_row_stride] = m;
global_pvals_copy[m * pvals_col_stride + n * pvals_row_stride] = 0.0; if (! %(replace)s )
cummul -= pvals_nm; {
global_pvals_copy[m * pvals_col_stride + n * pvals_row_stride] = 0.0;
cummul -= pvals_nm;
}
done = true; done = true;
} }
} }
// No need to renormalize after the last samples. // No need to renormalize after the last samples.
if (c == (n_samples - 1)) if (c == (n_samples - 1))
break; break;
// parallel renormalize the multinomial if (! %(replace)s )
for (ga_int k = LID_1; k < nb_outcomes; k+=LDIM_1)
{ {
global_pvals_copy[k * pvals_col_stride + n * pvals_row_stride] /= cummul; // parallel renormalize the multinomial
for (ga_int k = LID_1; k < nb_outcomes; k+=LDIM_1)
{
global_pvals_copy[k * pvals_col_stride + n * pvals_row_stride] /= cummul;
}
} }
} }
} }
} }
""" """ % {"replace": replace}
return [Kernel( return [Kernel(
code=code, name="k_multi_warp_multinomial_wor", code=code, name="k_multi_warp_multinomial_wor",
params=[pygpu.gpuarray.SIZE, params=[pygpu.gpuarray.SIZE,
......
...@@ -180,7 +180,7 @@ class test_OP_wor(unittest.TestCase): ...@@ -180,7 +180,7 @@ class test_OP_wor(unittest.TestCase):
p = tensor.fmatrix() p = tensor.fmatrix()
u = tensor.fvector() u = tensor.fvector()
n = tensor.iscalar() n = tensor.iscalar()
m = multinomial.ChoiceFromUniform('auto')(p, u, n) m = multinomial.ChoiceFromUniform(odtype='auto')(p, u, n)
f = function([p, u, n], m, allow_input_downcast=True) f = function([p, u, n], m, allow_input_downcast=True)
...@@ -204,7 +204,7 @@ class test_OP_wor(unittest.TestCase): ...@@ -204,7 +204,7 @@ class test_OP_wor(unittest.TestCase):
p = tensor.fmatrix() p = tensor.fmatrix()
u = tensor.fvector() u = tensor.fvector()
n = tensor.iscalar() n = tensor.iscalar()
m = multinomial.ChoiceFromUniform('auto')(p, u, n) m = multinomial.ChoiceFromUniform(odtype='auto')(p, u, n)
f = function([p, u, n], m, allow_input_downcast=True) f = function([p, u, n], m, allow_input_downcast=True)
...@@ -224,7 +224,7 @@ class test_OP_wor(unittest.TestCase): ...@@ -224,7 +224,7 @@ class test_OP_wor(unittest.TestCase):
p = tensor.fmatrix() p = tensor.fmatrix()
u = tensor.fvector() u = tensor.fvector()
n = tensor.iscalar() n = tensor.iscalar()
m = multinomial.ChoiceFromUniform('auto')(p, u, n) m = multinomial.ChoiceFromUniform(odtype='auto')(p, u, n)
f = function([p, u, n], m, allow_input_downcast=True) f = function([p, u, n], m, allow_input_downcast=True)
...@@ -327,7 +327,7 @@ def test_gpu_opt_wor(): ...@@ -327,7 +327,7 @@ def test_gpu_opt_wor():
p = tensor.fmatrix() p = tensor.fmatrix()
u = tensor.fvector() u = tensor.fvector()
n = tensor.iscalar() n = tensor.iscalar()
m = multinomial.ChoiceFromUniform('auto')(p, u, n) m = multinomial.ChoiceFromUniform(odtype='auto')(p, u, n)
assert m.dtype == 'int64', m.dtype assert m.dtype == 'int64', m.dtype
f = function([p, u, n], m, allow_input_downcast=True, mode=mode_with_gpu) f = function([p, u, n], m, allow_input_downcast=True, mode=mode_with_gpu)
......
...@@ -219,6 +219,17 @@ class ChoiceFromUniform(MultinomialFromUniform): ...@@ -219,6 +219,17 @@ class ChoiceFromUniform(MultinomialFromUniform):
""" """
__props__ = ("replace",)
def __init__(self, replace=False, *args, **kwargs):
self.replace = replace
super(ChoiceFromUniform, self).__init__(*args, **kwargs)
def __setstate__(self, state):
self.__dict__.update(state)
if "replace" not in state:
self.replace = False
def make_node(self, pvals, unis, n=1): def make_node(self, pvals, unis, n=1):
pvals = T.as_tensor_variable(pvals) pvals = T.as_tensor_variable(pvals)
unis = T.as_tensor_variable(unis) unis = T.as_tensor_variable(unis)
...@@ -239,6 +250,7 @@ class ChoiceFromUniform(MultinomialFromUniform): ...@@ -239,6 +250,7 @@ class ChoiceFromUniform(MultinomialFromUniform):
def c_code(self, node, name, ins, outs, sub): def c_code(self, node, name, ins, outs, sub):
(pvals, unis, n) = ins (pvals, unis, n) = ins
(z,) = outs (z,) = outs
replace = int(self.replace)
if self.odtype == 'auto': if self.odtype == 'auto':
t = "NPY_INT64" t = "NPY_INT64"
else: else:
...@@ -333,20 +345,23 @@ class ChoiceFromUniform(MultinomialFromUniform): ...@@ -333,20 +345,23 @@ class ChoiceFromUniform(MultinomialFromUniform):
// No need to renormalize after the last samples. // No need to renormalize after the last samples.
if (c == (n_samples - 1)) if (c == (n_samples - 1))
break; break;
// renormalize the nth row of pvals, reuse (cummul-*pvals_nm) to initialize the sum if (! %(replace)s )
dtype_%(pvals)s sum = cummul - *pvals_nm;
dtype_%(pvals)s* pvals_n = (dtype_%(pvals)s*)PyArray_GETPTR2(pvals_copy, n, m);
*pvals_nm = 0.;
for (int k = m; k < nb_outcomes; ++k)
{
sum = sum + *pvals_n;
pvals_n++;
}
pvals_n = (dtype_%(pvals)s*)PyArray_GETPTR2(pvals_copy, n, 0);
for (int k = 0; k < nb_outcomes; ++k)
{ {
*pvals_n = *pvals_n / sum; // renormalize the nth row of pvals, reuse (cummul-*pvals_nm) to initialize the sum
pvals_n++; dtype_%(pvals)s sum = cummul - *pvals_nm;
dtype_%(pvals)s* pvals_n = (dtype_%(pvals)s*)PyArray_GETPTR2(pvals_copy, n, m);
*pvals_nm = 0.;
for (int k = m; k < nb_outcomes; ++k)
{
sum = sum + *pvals_n;
pvals_n++;
}
pvals_n = (dtype_%(pvals)s*)PyArray_GETPTR2(pvals_copy, n, 0);
for (int k = 0; k < nb_outcomes; ++k)
{
*pvals_n = *pvals_n / sum;
pvals_n++;
}
} }
break; break;
} }
...@@ -398,8 +413,9 @@ class ChoiceFromUniform(MultinomialFromUniform): ...@@ -398,8 +413,9 @@ class ChoiceFromUniform(MultinomialFromUniform):
z[0][n, c] = m z[0][n, c] = m
# set to zero and re-normalize so that it's not # set to zero and re-normalize so that it's not
# selected again # selected again
pvals[n, m] = 0. if not self.replace:
pvals[n] /= pvals[n].sum() pvals[n, m] = 0.
pvals[n] /= pvals[n].sum()
break break
......
...@@ -1513,7 +1513,7 @@ class MRG_RandomStreams(object): ...@@ -1513,7 +1513,7 @@ class MRG_RandomStreams(object):
shape = p[:, 0].shape * size shape = p[:, 0].shape * size
unis = self.uniform(size=shape, ndim=1, nstreams=nstreams) unis = self.uniform(size=shape, ndim=1, nstreams=nstreams)
op = multinomial.ChoiceFromUniform(dtype) op = multinomial.ChoiceFromUniform(odtype=dtype)
return op(p, unis, as_tensor_variable(size)) return op(p, unis, as_tensor_variable(size))
def multinomial_wo_replacement(self, size=None, n=1, pvals=None, def multinomial_wo_replacement(self, size=None, n=1, pvals=None,
......
...@@ -18,7 +18,7 @@ class test_OP(unittest.TestCase): ...@@ -18,7 +18,7 @@ class test_OP(unittest.TestCase):
p = tensor.fmatrix() p = tensor.fmatrix()
u = tensor.fvector() u = tensor.fvector()
n = tensor.iscalar() n = tensor.iscalar()
m = multinomial.ChoiceFromUniform('auto')(p, u, n) m = multinomial.ChoiceFromUniform(odtype='auto')(p, u, n)
f = function([p, u, n], m, allow_input_downcast=True) f = function([p, u, n], m, allow_input_downcast=True)
...@@ -52,7 +52,7 @@ class test_OP(unittest.TestCase): ...@@ -52,7 +52,7 @@ class test_OP(unittest.TestCase):
p = tensor.fmatrix() p = tensor.fmatrix()
u = tensor.fvector() u = tensor.fvector()
n = tensor.iscalar() n = tensor.iscalar()
m = multinomial.ChoiceFromUniform('auto')(p, u, n) m = multinomial.ChoiceFromUniform(odtype='auto')(p, u, n)
f = function([p, u, n], m, allow_input_downcast=True) f = function([p, u, n], m, allow_input_downcast=True)
...@@ -72,7 +72,7 @@ class test_OP(unittest.TestCase): ...@@ -72,7 +72,7 @@ class test_OP(unittest.TestCase):
p = tensor.fmatrix() p = tensor.fmatrix()
u = tensor.fvector() u = tensor.fvector()
n = tensor.iscalar() n = tensor.iscalar()
m = multinomial.ChoiceFromUniform('auto')(p, u, n) m = multinomial.ChoiceFromUniform(odtype='auto')(p, u, n)
f = function([p, u, n], m, allow_input_downcast=True) f = function([p, u, n], m, allow_input_downcast=True)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论