Merge branch 'master' into ebarsoum/ImageHandsOn
For checkin....
This commit is contained in:
Коммит
bc2b046cdd
|
@ -936,12 +936,12 @@ namespace CNTK
|
|||
CNTK_API static UniqueDynamicAxesNames s_uniqueDynamicAxisNames;
|
||||
|
||||
public:
|
||||
CNTK_API static const std::vector<Axis> DefaultInputVariableDynamicAxes;
|
||||
CNTK_API static const std::vector<Axis>& DefaultInputVariableDynamicAxes();
|
||||
|
||||
///
|
||||
/// Axis object representing unknown dynamic axes
|
||||
///
|
||||
CNTK_API static const std::vector<Axis> UnknownDynamicAxes;
|
||||
CNTK_API static const std::vector<Axis>& UnknownDynamicAxes();
|
||||
|
||||
public:
|
||||
///
|
||||
|
@ -1548,8 +1548,8 @@ namespace CNTK
|
|||
typedef Dictionary ParameterInitializer;
|
||||
|
||||
// Forward declarations
|
||||
inline Variable PlaceholderVariable(const NDShape& shape, const std::wstring& name, const std::vector<Axis>& dynamicAxes = Axis::UnknownDynamicAxes);
|
||||
inline Variable InputVariable(const NDShape& shape, bool isSparse, ::CNTK::DataType dataType, bool needsGradient, const std::wstring& name, const std::vector<Axis>& dynamicAxes = Axis::DefaultInputVariableDynamicAxes);
|
||||
inline Variable PlaceholderVariable(const NDShape& shape, const std::wstring& name, const std::vector<Axis>& dynamicAxes = Axis::UnknownDynamicAxes());
|
||||
inline Variable InputVariable(const NDShape& shape, bool isSparse, ::CNTK::DataType dataType, bool needsGradient, const std::wstring& name, const std::vector<Axis>& dynamicAxes = Axis::DefaultInputVariableDynamicAxes());
|
||||
inline Variable OutputVariable(const NDShape& shape, ::CNTK::DataType dataType, Function* ownerFunction, const std::vector<Axis>& dynamicAxes, const std::wstring& name = L"");
|
||||
|
||||
///
|
||||
|
@ -1578,7 +1578,7 @@ namespace CNTK
|
|||
#ifndef SWIG
|
||||
private:
|
||||
friend inline Variable PlaceholderVariable(const NDShape& shape, const std::wstring& name, const std::vector<Axis>& dynamicAxes);
|
||||
friend inline Variable InputVariable(const NDShape& shape, bool isSparse, ::CNTK::DataType dataType, bool needsGradient, const std::wstring& name, const std::vector<Axis>& dynamicAxes /*= Axis::DefaultInputVariableDynamicAxes*/);
|
||||
friend inline Variable InputVariable(const NDShape& shape, bool isSparse, ::CNTK::DataType dataType, bool needsGradient, const std::wstring& name, const std::vector<Axis>& dynamicAxes /*= Axis::DefaultInputVariableDynamicAxes()*/);
|
||||
friend inline Variable OutputVariable(const NDShape& shape, ::CNTK::DataType dataType, Function* ownerFunction, const std::vector<Axis>& dynamicAxes, const std::wstring& name /*= L""*/);
|
||||
#endif
|
||||
|
||||
|
@ -1812,7 +1812,7 @@ private:
|
|||
/// Create a Placeholder variable to be used as a temporary/placeholder input to a Function.
|
||||
/// All placeholder inputs of a Function must be replaced with non-placeholder Variables before Forward evaluation of the Function.
|
||||
///
|
||||
inline Variable PlaceholderVariable(const NDShape& shape, const std::vector<Axis>& dynamicAxes = Axis::UnknownDynamicAxes)
|
||||
inline Variable PlaceholderVariable(const NDShape& shape, const std::vector<Axis>& dynamicAxes = Axis::UnknownDynamicAxes())
|
||||
{
|
||||
return PlaceholderVariable(shape, L"", dynamicAxes);
|
||||
}
|
||||
|
@ -1823,13 +1823,13 @@ private:
|
|||
///
|
||||
inline Variable PlaceholderVariable(const std::wstring& name = L"")
|
||||
{
|
||||
return PlaceholderVariable(NDShape::Unknown, name, Axis::UnknownDynamicAxes);
|
||||
return PlaceholderVariable(NDShape::Unknown, name, Axis::UnknownDynamicAxes());
|
||||
}
|
||||
|
||||
///
|
||||
/// Create an 'Input' Variable denoting sparse data and specify if gradients are to be computed for this input
|
||||
///
|
||||
inline Variable InputVariable(const NDShape& shape, bool isSparse, ::CNTK::DataType dataType, bool needsGradient, const std::wstring& name /*= L""*/, const std::vector<Axis>& dynamicAxes /*= Axis::DefaultInputVariableDynamicAxes*/)
|
||||
inline Variable InputVariable(const NDShape& shape, bool isSparse, ::CNTK::DataType dataType, bool needsGradient, const std::wstring& name /*= L""*/, const std::vector<Axis>& dynamicAxes /*= Axis::DefaultInputVariableDynamicAxes()*/)
|
||||
{
|
||||
return Variable(shape, isSparse, dataType, needsGradient, name, dynamicAxes, Internal::GenerateUid(VariableKind::Input));
|
||||
}
|
||||
|
@ -1837,7 +1837,7 @@ private:
|
|||
///
|
||||
/// Create an 'Input' Variable and specify if gradients are to be computed for this input
|
||||
///
|
||||
inline Variable InputVariable(const NDShape& shape, ::CNTK::DataType dataType, bool needsGradient, const std::wstring& name = L"", const std::vector<Axis>& dynamicAxes = Axis::DefaultInputVariableDynamicAxes)
|
||||
inline Variable InputVariable(const NDShape& shape, ::CNTK::DataType dataType, bool needsGradient, const std::wstring& name = L"", const std::vector<Axis>& dynamicAxes = Axis::DefaultInputVariableDynamicAxes())
|
||||
{
|
||||
return InputVariable(shape, /*isSparse =*/ false, dataType, needsGradient, name, dynamicAxes);
|
||||
}
|
||||
|
@ -1845,7 +1845,7 @@ private:
|
|||
///
|
||||
/// Create an 'Input' Variable.
|
||||
///
|
||||
inline Variable InputVariable(const NDShape& shape, DataType dataType, const std::wstring& name, const std::vector<Axis>& dynamicAxes = Axis::DefaultInputVariableDynamicAxes)
|
||||
inline Variable InputVariable(const NDShape& shape, DataType dataType, const std::wstring& name, const std::vector<Axis>& dynamicAxes = Axis::DefaultInputVariableDynamicAxes())
|
||||
{
|
||||
return InputVariable(shape, dataType, /*needsGradient =*/ false, name, dynamicAxes);
|
||||
}
|
||||
|
@ -1853,7 +1853,7 @@ private:
|
|||
///
|
||||
/// Create an 'Input' Variable.
|
||||
///
|
||||
inline Variable InputVariable(const NDShape& shape, DataType dataType, const wchar_t* name, const std::vector<Axis>& dynamicAxes = Axis::DefaultInputVariableDynamicAxes)
|
||||
inline Variable InputVariable(const NDShape& shape, DataType dataType, const wchar_t* name, const std::vector<Axis>& dynamicAxes = Axis::DefaultInputVariableDynamicAxes())
|
||||
{
|
||||
return InputVariable(shape, dataType, std::wstring(name), dynamicAxes);
|
||||
}
|
||||
|
@ -1861,7 +1861,7 @@ private:
|
|||
///
|
||||
/// Create an 'Input' Variable.
|
||||
///
|
||||
inline Variable InputVariable(const NDShape& shape, DataType dataType, const std::vector<Axis>& dynamicAxes = Axis::DefaultInputVariableDynamicAxes)
|
||||
inline Variable InputVariable(const NDShape& shape, DataType dataType, const std::vector<Axis>& dynamicAxes = Axis::DefaultInputVariableDynamicAxes())
|
||||
{
|
||||
return InputVariable(shape, dataType, L"", dynamicAxes);
|
||||
}
|
||||
|
@ -1869,7 +1869,7 @@ private:
|
|||
///
|
||||
/// Create an 'Input' Variable denoting sparse data.
|
||||
///
|
||||
inline Variable InputVariable(const NDShape& shape, bool isSparse, ::CNTK::DataType dataType, const std::wstring& name, const std::vector<Axis>& dynamicAxes = Axis::DefaultInputVariableDynamicAxes)
|
||||
inline Variable InputVariable(const NDShape& shape, bool isSparse, ::CNTK::DataType dataType, const std::wstring& name, const std::vector<Axis>& dynamicAxes = Axis::DefaultInputVariableDynamicAxes())
|
||||
{
|
||||
return InputVariable(shape, isSparse, dataType, /*needsGradient =*/ false, name, dynamicAxes);
|
||||
}
|
||||
|
@ -1877,7 +1877,7 @@ private:
|
|||
///
|
||||
/// Create an 'Input' Variable denoting sparse data.
|
||||
///
|
||||
inline Variable InputVariable(const NDShape& shape, bool isSparse, ::CNTK::DataType dataType, const wchar_t* name, const std::vector<Axis>& dynamicAxes = Axis::DefaultInputVariableDynamicAxes)
|
||||
inline Variable InputVariable(const NDShape& shape, bool isSparse, ::CNTK::DataType dataType, const wchar_t* name, const std::vector<Axis>& dynamicAxes = Axis::DefaultInputVariableDynamicAxes())
|
||||
{
|
||||
return InputVariable(shape, isSparse, dataType, std::wstring(name), dynamicAxes);
|
||||
}
|
||||
|
@ -1885,7 +1885,7 @@ private:
|
|||
///
|
||||
/// Create an 'Input' Variable denoting sparse data.
|
||||
///
|
||||
inline Variable InputVariable(const NDShape& shape, bool isSparse, ::CNTK::DataType dataType, const std::vector<Axis>& dynamicAxes = Axis::DefaultInputVariableDynamicAxes)
|
||||
inline Variable InputVariable(const NDShape& shape, bool isSparse, ::CNTK::DataType dataType, const std::vector<Axis>& dynamicAxes = Axis::DefaultInputVariableDynamicAxes())
|
||||
{
|
||||
return InputVariable(shape, isSparse, dataType, L"", dynamicAxes);
|
||||
}
|
||||
|
|
|
@ -253,4 +253,4 @@ namespace CNTK
|
|||
std::unordered_map<::CNTK::Variable, ::CNTK::Variable>& placeholderReplacements,
|
||||
std::unordered_set<::CNTK::FunctionPtr>& allPrimitiveFunctions);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -267,7 +267,8 @@ namespace CNTK
|
|||
|
||||
/*static*/ DeviceDescriptor DeviceDescriptor::DefaultDevice()
|
||||
{
|
||||
std::call_once(s_initDefaultDeviceFlag, [=]{
|
||||
std::call_once(s_initDefaultDeviceFlag, []
|
||||
{
|
||||
s_defaultDevice.reset(new DeviceDescriptor(DeviceDescriptor::BestDevice()));
|
||||
});
|
||||
return *s_defaultDevice;
|
||||
|
@ -293,7 +294,8 @@ namespace CNTK
|
|||
if (!Internal::IsSettingDefaultDeviceAlwaysAllowed() && s_defaultDeviceFrozen.load())
|
||||
RuntimeError("Process wide default device cannot be changed since it has been frozen by being implicitly used as the default device in a CNTK API call");
|
||||
|
||||
std::call_once(s_initDefaultDeviceFlag, []{
|
||||
std::call_once(s_initDefaultDeviceFlag, []
|
||||
{
|
||||
// do nothing. This will set the flag above, in case when DefaultDevice() was never called before.
|
||||
});
|
||||
|
||||
|
@ -313,7 +315,8 @@ namespace CNTK
|
|||
{
|
||||
using namespace Microsoft::MSR::CNTK;
|
||||
|
||||
std::call_once(s_initAllDevicesFlag, [=]{
|
||||
std::call_once(s_initAllDevicesFlag, []
|
||||
{
|
||||
s_allDevices.reset(new std::vector<DeviceDescriptor>());
|
||||
#ifndef CPUONLY
|
||||
auto allGpusData = GetAllGpusData();
|
||||
|
@ -352,8 +355,26 @@ namespace CNTK
|
|||
|
||||
/*static*/ Axis::UniqueDynamicAxesNames Axis::s_uniqueDynamicAxisNames;
|
||||
|
||||
/*static*/ const std::vector<Axis> Axis::DefaultInputVariableDynamicAxes = { Axis::DefaultDynamicAxis(), Axis::DefaultBatchAxis() };
|
||||
/*static*/ const std::vector<Axis> Axis::UnknownDynamicAxes = { Axis(SentinelStaticAxisIndexValueForUnknownAxes) };
|
||||
static std::shared_ptr<std::vector<Axis>> s_defaultInputVariableDynamicAxes, s_unknownDynamicAxes;
|
||||
static std::once_flag s_initDefaultInputVariableDynamicAxesFlag, s_initUnknownDynamicAxesFlag;
|
||||
|
||||
/*static*/ const std::vector<Axis>& Axis::DefaultInputVariableDynamicAxes()
|
||||
{
|
||||
std::call_once(s_initDefaultInputVariableDynamicAxesFlag, []
|
||||
{
|
||||
s_defaultInputVariableDynamicAxes.reset(new std::vector<Axis>({ Axis::DefaultDynamicAxis(), Axis::DefaultBatchAxis() }));
|
||||
});
|
||||
return *s_defaultInputVariableDynamicAxes;
|
||||
}
|
||||
|
||||
/*static*/ const std::vector<Axis>& Axis::UnknownDynamicAxes()
|
||||
{
|
||||
std::call_once(s_initUnknownDynamicAxesFlag, []
|
||||
{
|
||||
s_unknownDynamicAxes.reset(new std::vector<Axis>({ Axis(SentinelStaticAxisIndexValueForUnknownAxes) }));
|
||||
});
|
||||
return *s_unknownDynamicAxes;
|
||||
}
|
||||
|
||||
/*static*/ const Axis& Axis::DefaultDynamicAxis()
|
||||
{
|
||||
|
|
|
@ -92,7 +92,7 @@ namespace CNTK
|
|||
if (var.Shape().IsUnknown() && !placeholder.Shape().IsUnknown())
|
||||
var.m_dataFields->m_shape = placeholder.Shape();
|
||||
|
||||
if ((var.DynamicAxes() == Axis::UnknownDynamicAxes) && (placeholder.DynamicAxes() != Axis::UnknownDynamicAxes))
|
||||
if ((var.DynamicAxes() == Axis::UnknownDynamicAxes()) && (placeholder.DynamicAxes() != Axis::UnknownDynamicAxes()))
|
||||
var.m_dataFields->m_dynamicAxes = placeholder.DynamicAxes();
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ namespace CNTK
|
|||
currentOutputVar.m_dataFields->m_dataType = newOutputVar.GetDataType();
|
||||
}
|
||||
|
||||
if ((currentOutputVar.DynamicAxes() == Axis::UnknownDynamicAxes) && (currentOutputVar.DynamicAxes() != newOutputVar.DynamicAxes()))
|
||||
if ((currentOutputVar.DynamicAxes() == Axis::UnknownDynamicAxes()) && (currentOutputVar.DynamicAxes() != newOutputVar.DynamicAxes()))
|
||||
{
|
||||
recurrentNodeOutputModified = true;
|
||||
currentOutputVar.m_dataFields->m_dynamicAxes = newOutputVar.DynamicAxes();
|
||||
|
@ -172,7 +172,7 @@ namespace CNTK
|
|||
|
||||
if ((!newOutputVar.Shape().IsUnknown() && (currentOutputVar.Shape() != newOutputVar.Shape())) ||
|
||||
((newOutputVar.GetDataType() != DataType::Unknown) && (currentOutputVar.GetDataType() != newOutputVar.GetDataType())) ||
|
||||
((newOutputVar.DynamicAxes() != Axis::UnknownDynamicAxes) && (currentOutputVar.DynamicAxes() != newOutputVar.DynamicAxes())))
|
||||
((newOutputVar.DynamicAxes() != Axis::UnknownDynamicAxes()) && (currentOutputVar.DynamicAxes() != newOutputVar.DynamicAxes())))
|
||||
{
|
||||
InvalidArgument("Inconsistency in output variable shape, DataType or Dynamic axes computed after replaced placeholders vs. existing output properties, for the Recurrent Function");
|
||||
}
|
||||
|
@ -642,13 +642,13 @@ namespace CNTK
|
|||
auto allInputDynamicAxesEmpty = std::find_if(inputs.begin(), inputs.end(), [](const Variable& input) { return !input.DynamicAxes().empty(); }) == inputs.end();
|
||||
if (!allInputDynamicAxesEmpty)
|
||||
{
|
||||
outputDynamicAxes = Axis::UnknownDynamicAxes;
|
||||
outputDynamicAxes = Axis::UnknownDynamicAxes();
|
||||
for (auto inputVar : inputs)
|
||||
{
|
||||
auto currentInputDynamicAxes = inputVar.DynamicAxes();
|
||||
if (!currentInputDynamicAxes.empty() && (currentInputDynamicAxes != Axis::UnknownDynamicAxes))
|
||||
if (!currentInputDynamicAxes.empty() && (currentInputDynamicAxes != Axis::UnknownDynamicAxes()))
|
||||
{
|
||||
if (outputDynamicAxes == Axis::UnknownDynamicAxes)
|
||||
if (outputDynamicAxes == Axis::UnknownDynamicAxes())
|
||||
outputDynamicAxes = currentInputDynamicAxes;
|
||||
else
|
||||
{
|
||||
|
@ -808,7 +808,7 @@ namespace CNTK
|
|||
Variable initialStateVar = inputs[1];
|
||||
|
||||
// TODO: We currently only support input operand with 1 dynamic axis for PastValue/FutureValue
|
||||
if ((inputOperandVar.DynamicAxes() != Axis::UnknownDynamicAxes) && (inputOperandVar.DynamicAxes().size() != 2))
|
||||
if ((inputOperandVar.DynamicAxes() != Axis::UnknownDynamicAxes()) && (inputOperandVar.DynamicAxes().size() != 2))
|
||||
LogicError("Currently PastValue/FutureValue Function only supports input operand with 2 dynamic axis (1 sequence-axis and 1 batch-axis)");
|
||||
|
||||
if (!initialStateVar.DynamicAxes().empty())
|
||||
|
@ -1322,7 +1322,7 @@ namespace CNTK
|
|||
if (variable.Shape().HasInferredDimension())
|
||||
InvalidArgument("Variable%S with InferredDimension for at least one axis in its shape, detected when compiling the Function graph!", ParanthesizedName(variable.Name()).c_str());
|
||||
|
||||
if (variable.DynamicAxes() == Axis::UnknownDynamicAxes)
|
||||
if (variable.DynamicAxes() == Axis::UnknownDynamicAxes())
|
||||
InvalidArgument("Variable%S with unknown dynamic axes detected when compiling the Function graph!", ParanthesizedName(variable.Name()).c_str());
|
||||
|
||||
// Lets add a null entry in the map for this variable, to break infinite recursion when processing recurrent graphs
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//%feature("autodoc", "1");
|
||||
|
||||
%include "stl.i"
|
||||
%include "std_wstring.i"
|
||||
%include "std_wstring.i"
|
||||
%include <std_vector.i>
|
||||
%include <std_map.i>
|
||||
%include <std_set.i>
|
||||
|
@ -74,9 +74,210 @@
|
|||
//
|
||||
%feature("shadow") CNTK::Variable::DynamicAxes %{
|
||||
def dynamic_axes(self):
|
||||
return tuple(reversed($action(self)))
|
||||
return ($action(self))[::-1]
|
||||
%}
|
||||
|
||||
%fragment("NDShapeToTuple", "header")
|
||||
{
|
||||
PyObject *NDShapeToTuple(const CNTK::NDShape& shape)
|
||||
{
|
||||
size_t rank = shape.Rank();
|
||||
auto result = PyTuple_New(rank);
|
||||
for (size_t i=0; i<rank; i++)
|
||||
{
|
||||
size_t dim = (&shape)->operator[](i);
|
||||
PyTuple_SetItem(result, i, PyInt_FromLong(dim));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
%fragment("NDArrayViewToNumPy", "header")
|
||||
{
|
||||
PyObject* NDArrayViewToNumPy(const CNTK::NDArrayView* self) {
|
||||
if ((*self).GetStorageFormat() != StorageFormat::Dense)
|
||||
throw std::invalid_argument("only dense supported at the moment");
|
||||
|
||||
// FIXME use not yet existing NDShape function that returns the dimensions at once
|
||||
std::vector<size_t> dimensions_cntk = (*self).Shape().Dimensions();
|
||||
std::vector<size_t> dimensions;
|
||||
|
||||
// We have at least one element. In case the shape is empty (e.g.
|
||||
// '()'), we have a scalar, which we need to copy (e.g. a constant).
|
||||
size_t num_elements = 1;
|
||||
|
||||
// CNTK uses column major, thus we reverse the shape
|
||||
for (int i=dimensions_cntk.size()-1; i>=0; i--)
|
||||
{
|
||||
dimensions.push_back(dimensions_cntk[i]);
|
||||
num_elements *= dimensions_cntk[i];
|
||||
}
|
||||
|
||||
npy_intp* shape = reinterpret_cast<npy_intp*>(&dimensions[0]);
|
||||
|
||||
CNTK::DataType cntk_type = (*self).GetDataType();
|
||||
|
||||
NDArrayView* cpuView;
|
||||
if ((*self).Device() != DeviceDescriptor::CPUDevice())
|
||||
{
|
||||
cpuView = new NDArrayView(cntk_type, (*self).Shape(), DeviceDescriptor::CPUDevice());
|
||||
cpuView->CopyFrom((*self));
|
||||
}
|
||||
else
|
||||
{
|
||||
cpuView = const_cast<NDArrayView*>(&(*self));
|
||||
}
|
||||
|
||||
NPY_TYPES numpy_type;
|
||||
void* buffer;
|
||||
|
||||
if (cntk_type == CNTK::DataType::Float)
|
||||
{
|
||||
numpy_type = NPY_FLOAT;
|
||||
buffer = (void*)cpuView->DataBuffer<float>();
|
||||
}
|
||||
else if (cntk_type == CNTK::DataType::Double)
|
||||
{
|
||||
numpy_type = NPY_DOUBLE;
|
||||
buffer = (void*)cpuView->DataBuffer<double>();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::invalid_argument("unknown CNTK data type");
|
||||
}
|
||||
|
||||
PyObject* ndarray = PyArray_SimpleNew(dimensions.size(), shape, numpy_type);
|
||||
void *arr_data = PyArray_DATA((PyArrayObject*)ndarray);
|
||||
|
||||
memcpy(arr_data, buffer, PyArray_ITEMSIZE((PyArrayObject*) ndarray) * num_elements);
|
||||
|
||||
if ((*self).Device() != DeviceDescriptor::CPUDevice())
|
||||
{
|
||||
delete cpuView;
|
||||
}
|
||||
|
||||
return ndarray;
|
||||
}
|
||||
}
|
||||
|
||||
%fragment("DictionaryValueToPy", "header", fragment="NDShapeToTuple", fragment="NDArrayViewToNumPy")
|
||||
{
|
||||
PyObject *DictionaryValueToPy(const CNTK::DictionaryValue& dictVal)
|
||||
{
|
||||
PyObject *val = nullptr;
|
||||
switch (dictVal.ValueType())
|
||||
{
|
||||
case CNTK::DictionaryValue::Type::None:
|
||||
Py_INCREF(Py_None);
|
||||
val = Py_None;
|
||||
break;
|
||||
case CNTK::DictionaryValue::Type::Bool:
|
||||
val = PyBool_FromLong(static_cast<long>(dictVal.Value<bool>()));
|
||||
break;
|
||||
case CNTK::DictionaryValue::Type::Int:
|
||||
val = PyLong_FromLong(static_cast<long>(dictVal.Value<int>()));
|
||||
break;
|
||||
case CNTK::DictionaryValue::Type::SizeT:
|
||||
val = PyLong_FromSize_t(dictVal.Value<size_t>());
|
||||
break;
|
||||
case CNTK::DictionaryValue::Type::Float:
|
||||
val = PyFloat_FromDouble(static_cast<double>(dictVal.Value<float>()));
|
||||
break;
|
||||
case CNTK::DictionaryValue::Type::Double:
|
||||
val = PyFloat_FromDouble(dictVal.Value<double>());
|
||||
break;
|
||||
case CNTK::DictionaryValue::Type::String:
|
||||
val = PyUnicode_FromWideChar(dictVal.Value<std::wstring>().c_str(), dictVal.Value<std::wstring>().length());
|
||||
break;
|
||||
case CNTK::DictionaryValue::Type::NDShape:
|
||||
val = NDShapeToTuple(dictVal.Value<CNTK::NDShape>());
|
||||
break;
|
||||
case CNTK::DictionaryValue::Type::Axis:
|
||||
val = PyTuple_New(3);
|
||||
if (val == NULL)
|
||||
{
|
||||
SWIG_exception(SWIG_RuntimeError, "error creating tuple for axis");
|
||||
}
|
||||
if (dictVal.Value<CNTK::Axis>().IsOrdered())
|
||||
PyTuple_SetItem(val, 0, PyUnicode_FromWideChar(L"ordered", 7));
|
||||
else
|
||||
PyTuple_SetItem(val, 0, PyUnicode_FromWideChar(L"unordered", 9));
|
||||
if (dictVal.Value<CNTK::Axis>().IsDynamicAxis())
|
||||
{
|
||||
PyTuple_SetItem(val, 1, PyUnicode_FromWideChar(L"dynamic", 7));
|
||||
PyTuple_SetItem(val, 2, PyUnicode_FromWideChar(
|
||||
dictVal.Value<CNTK::Axis>().Name().c_str(),
|
||||
dictVal.Value<CNTK::Axis>().Name().length()));
|
||||
}
|
||||
else
|
||||
{
|
||||
PyTuple_SetItem(val, 1, PyUnicode_FromWideChar(L"static", 6));
|
||||
PyTuple_SetItem(val, 2, PyLong_FromLong(
|
||||
static_cast<long>(
|
||||
dictVal.Value<CNTK::Axis>().StaticAxisIndex(true)
|
||||
)));
|
||||
}
|
||||
break;
|
||||
case CNTK::DictionaryValue::Type::Vector:
|
||||
val = PyList_New(0);
|
||||
if (val == NULL)
|
||||
{
|
||||
SWIG_exception(SWIG_RuntimeError, "error creating list");
|
||||
}
|
||||
for (auto it: dictVal.Value<std::vector<CNTK::DictionaryValue> >())
|
||||
{
|
||||
PyObject* tmp = DictionaryValueToPy(it);
|
||||
PyList_Append(val, tmp);
|
||||
Py_DECREF(tmp);
|
||||
}
|
||||
break;
|
||||
case CNTK::DictionaryValue::Type::Dictionary:
|
||||
val = PyDict_New();
|
||||
if (val == NULL)
|
||||
{
|
||||
SWIG_exception(SWIG_RuntimeError, "error creating dict");
|
||||
}
|
||||
for (auto it = dictVal.Value<CNTK::Dictionary>().begin(); it != dictVal.Value<CNTK::Dictionary>().end(); ++it)
|
||||
{
|
||||
PyObject *key = PyUnicode_FromWideChar(it->first.c_str(), it->first.length());
|
||||
PyObject *dvp = DictionaryValueToPy(it->second);
|
||||
PyDict_SetItem(val, key, dvp);
|
||||
Py_DECREF(key);
|
||||
Py_DECREF(val);
|
||||
}
|
||||
break;
|
||||
case CNTK::DictionaryValue::Type::NDArrayView:
|
||||
val = NDArrayViewToNumPy(&(dictVal.Value<CNTK::NDArrayView>()));
|
||||
break;
|
||||
default:
|
||||
SWIG_exception(SWIG_RuntimeError, "unknown type for DictionaryValue object");
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
fail:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
%typemap(out, fragment="DictionaryValueToPy") const CNTK::Dictionary& Attributes(){
|
||||
PyObject* container = PyDict_New();
|
||||
if (container == NULL)
|
||||
{
|
||||
SWIG_exception(SWIG_RuntimeError, "error passing dictionary to Python");
|
||||
}
|
||||
|
||||
for (auto it = $1->begin(); it != $1->end(); ++it)
|
||||
{
|
||||
PyObject *key = PyUnicode_FromWideChar(it->first.c_str(), it->first.length());
|
||||
PyObject *val = DictionaryValueToPy(it->second);
|
||||
PyDict_SetItem(container, key, val);
|
||||
Py_DECREF(key);
|
||||
Py_DECREF(val);
|
||||
}
|
||||
$result = container;
|
||||
}
|
||||
|
||||
|
||||
%define %eq_for(DATA_TYPE, EQ)
|
||||
%rename(EQ) operator==(const DATA_TYPE&, const DATA_TYPE&);
|
||||
%enddef
|
||||
|
@ -98,6 +299,12 @@ def dynamic_axes(self):
|
|||
}
|
||||
}
|
||||
|
||||
%extend CNTK::Axis {
|
||||
bool __eq__(const CNTK::Axis& other) const {
|
||||
return *$self == other;
|
||||
}
|
||||
}
|
||||
|
||||
%{
|
||||
#include "CNTKLibrary.h"
|
||||
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
|
||||
|
@ -122,8 +329,8 @@ def dynamic_axes(self):
|
|||
}
|
||||
|
||||
|
||||
//
|
||||
// NDShape
|
||||
//
|
||||
// NDShape
|
||||
//
|
||||
%typecheck(1000) CNTK::NDShape const &, CNTK::NDShape {
|
||||
// '1000' is the typecheck precedence code. It means: check after basic
|
||||
|
@ -152,14 +359,8 @@ def dynamic_axes(self):
|
|||
%ignore CNTK::NDShape::AppendShape;
|
||||
%ignore CNTK::NDShape::Dimensions;
|
||||
|
||||
%typemap(out) CNTK::NDShape {
|
||||
size_t rank = $1.Rank();
|
||||
$result = PyTuple_New(rank);
|
||||
for (size_t i=0; i<rank; i++)
|
||||
{
|
||||
size_t dim = (&$1)->operator[](i);
|
||||
PyTuple_SET_ITEM($result, i, PyInt_FromLong(dim));
|
||||
}
|
||||
%typemap(out, fragment="NDShapeToTuple") CNTK::NDShape {
|
||||
$result = NDShapeToTuple($1);
|
||||
}
|
||||
|
||||
%extend CNTK::NDShape {
|
||||
|
@ -173,7 +374,7 @@ def dynamic_axes(self):
|
|||
return (*self)[rank-1-i];
|
||||
}
|
||||
|
||||
PyObject* dimensions() {
|
||||
PyObject* dimensions() {
|
||||
std::vector<size_t> dims = (*self).Dimensions();
|
||||
size_t rank = (*self).Rank();
|
||||
PyObject* result = PyTuple_New(rank);
|
||||
|
@ -181,7 +382,7 @@ def dynamic_axes(self):
|
|||
for (size_t i=0; i<rank; i++)
|
||||
{
|
||||
size_t dim = dims[i];
|
||||
PyTuple_SET_ITEM(result, rank-1-i, PyInt_FromLong(dim));
|
||||
PyTuple_SET_ITEM(result, rank-1-i, PyInt_FromLong(dim));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -199,7 +400,7 @@ def dynamic_axes(self):
|
|||
//%constant long CNTK::NDShape::InferredDimension = -1;
|
||||
%constant long InferredDimension = -1;
|
||||
|
||||
// end of NDShape
|
||||
// end of NDShape
|
||||
|
||||
//
|
||||
// Converting Python dictionary {Variable: ValuePtr} to std::unordered_map
|
||||
|
@ -222,7 +423,7 @@ def dynamic_axes(self):
|
|||
void *raw_var = 0 ;
|
||||
int res1 = SWIG_ConvertPtr(key, &raw_var, SWIGTYPE_p_CNTK__Variable, 0);
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert key of dictionary to CNTK::Variable");
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert key of dictionary to CNTK::Variable");
|
||||
}
|
||||
if (!raw_var) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "invalid null reference when converting key of dictionary to CNTK::Variable");
|
||||
|
@ -233,7 +434,7 @@ def dynamic_axes(self):
|
|||
void *raw_value = 0;
|
||||
int res2 = SWIG_ConvertPtr(value, &raw_value, SWIGTYPE_p_std__shared_ptrT_CNTK__Value_t, 0);
|
||||
if (!SWIG_IsOK(res2)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res2), "cannot convert value of dictionary to CNTK::ValuePtr");
|
||||
SWIG_exception_fail(SWIG_ArgError(res2), "cannot convert value of dictionary to CNTK::ValuePtr");
|
||||
}
|
||||
|
||||
CNTK::ValuePtr* value;
|
||||
|
@ -266,7 +467,7 @@ def dynamic_axes(self):
|
|||
void *raw_var = 0 ;
|
||||
int res1 = SWIG_ConvertPtr(key, &raw_var, SWIGTYPE_p_CNTK__Variable, 0);
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert key of dictionary to CNTK::Variable");
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert key of dictionary to CNTK::Variable");
|
||||
}
|
||||
if (!raw_var) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "invalid null reference when converting key of dictionary to CNTK::Variable");
|
||||
|
@ -277,7 +478,7 @@ def dynamic_axes(self):
|
|||
void *raw_value = 0;
|
||||
int res2 = SWIG_ConvertPtr(value, &raw_value, SWIGTYPE_p_std__shared_ptrT_CNTK__Value_t, 0);
|
||||
if (!SWIG_IsOK(res2)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res2), "cannot convert value of dictionary to CNTK::ValuePtr");
|
||||
SWIG_exception_fail(SWIG_ArgError(res2), "cannot convert value of dictionary to CNTK::ValuePtr");
|
||||
}
|
||||
|
||||
CNTK::ValuePtr* value;
|
||||
|
@ -300,10 +501,10 @@ def dynamic_axes(self):
|
|||
// modified values and put them back into the dictionary. This is used, when
|
||||
// e.g. the user puts a variable into the dictionary, hoping that it will
|
||||
// afterwards point to the proper value.
|
||||
%typemap(argout)
|
||||
// Swig would create this conversion for the 'const' variants as well, which
|
||||
%typemap(argout)
|
||||
// Swig would create this conversion for the 'const' variants as well, which
|
||||
// we do not want. Therefor, we have to explicitly tell it for which ones it should do it.
|
||||
std::unordered_map<CNTK::Variable, CNTK::ValuePtr>& outputsToFetch,
|
||||
std::unordered_map<CNTK::Variable, CNTK::ValuePtr>& outputsToFetch,
|
||||
std::unordered_map<CNTK::Variable, CNTK::ValuePtr>& outputs,
|
||||
std::unordered_map<CNTK::Variable, CNTK::ValuePtr>& backPropagatedGradientValuesForInputs
|
||||
{
|
||||
|
@ -338,7 +539,7 @@ def dynamic_axes(self):
|
|||
void *cntk_key = 0 ;
|
||||
int res = SWIG_ConvertPtr(py_key, &cntk_key, SWIGTYPE_p_CNTK__Variable, 0);
|
||||
if (!SWIG_IsOK(res)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res), "cannot convert key of dictionary to CNTK::Variable");
|
||||
SWIG_exception_fail(SWIG_ArgError(res), "cannot convert key of dictionary to CNTK::Variable");
|
||||
}
|
||||
if (!cntk_key) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "invalid null reference when converting key of dictionary to CNTK::Variable");
|
||||
|
@ -376,7 +577,7 @@ def dynamic_axes(self):
|
|||
void *raw_var = 0 ;
|
||||
int res1 = SWIG_ConvertPtr(key, &raw_var, SWIGTYPE_p_CNTK__StreamInformation, 0);
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert key of dictionary to CNTK::StreamInformation");
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert key of dictionary to CNTK::StreamInformation");
|
||||
}
|
||||
if (!raw_var) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "invalid null reference when converting key of dictionary to CNTK::StreamInformation");
|
||||
|
@ -388,14 +589,14 @@ def dynamic_axes(self):
|
|||
|
||||
if (PyTuple_Check(value)) {
|
||||
PyObject* first = PyTuple_GET_ITEM(value, 0);
|
||||
size_t first_val = PyLong_AsSize_t(first);
|
||||
PyObject* second = PyTuple_GET_ITEM(value, 1);
|
||||
size_t first_val = PyLong_AsSize_t(first);
|
||||
PyObject* second = PyTuple_GET_ITEM(value, 1);
|
||||
size_t second_val = PyLong_AsSize_t(second);
|
||||
args_map.insert(std::make_pair(*var, std::make_pair(first_val, second_val)));
|
||||
} else {
|
||||
SWIG_exception(SWIG_TypeError, "tuple expected");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
$1 = &args_map;
|
||||
|
@ -411,7 +612,7 @@ def dynamic_axes(self):
|
|||
}
|
||||
|
||||
%typemap(in) std::unordered_map<CNTK::StreamInformation, std::pair<CNTK::NDArrayViewPtr, CNTK::NDArrayViewPtr>>& (
|
||||
std::unordered_map<CNTK::StreamInformation, std::pair<CNTK::NDArrayViewPtr, CNTK::NDArrayViewPtr>> args_map
|
||||
std::unordered_map<CNTK::StreamInformation, std::pair<CNTK::NDArrayViewPtr, CNTK::NDArrayViewPtr>> args_map
|
||||
){
|
||||
if (PyDict_Check($input)) {
|
||||
|
||||
|
@ -422,20 +623,20 @@ def dynamic_axes(self):
|
|||
void *raw_var = 0 ;
|
||||
int res = SWIG_ConvertPtr(key, &raw_var, SWIGTYPE_p_CNTK__StreamInformation, 0);
|
||||
if (!SWIG_IsOK(res)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res), "cannot convert key of dictionary to CNTK::StreamInformation");
|
||||
SWIG_exception_fail(SWIG_ArgError(res), "cannot convert key of dictionary to CNTK::StreamInformation");
|
||||
}
|
||||
if (!raw_var) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "invalid null reference when converting key of dictionary to CNTK::StreamInformation");
|
||||
}
|
||||
|
||||
CNTK::StreamInformation* var = reinterpret_cast<CNTK::StreamInformation*>(raw_var);
|
||||
CNTK::StreamInformation* var = reinterpret_cast<CNTK::StreamInformation*>(raw_var);
|
||||
|
||||
if (PyTuple_Check(value)) {
|
||||
PyObject* first = PyTuple_GET_ITEM(value, 0);
|
||||
void *raw_value1 = 0;
|
||||
int res1 = SWIG_ConvertPtr(first, &raw_value1, SWIGTYPE_p_std__shared_ptrT_CNTK__NDArrayView_t, 0);
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert value of dictionary to CNTK::NDArrayViewPtr");
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert value of dictionary to CNTK::NDArrayViewPtr");
|
||||
}
|
||||
|
||||
CNTK::NDArrayViewPtr* value1;
|
||||
|
@ -446,11 +647,11 @@ def dynamic_axes(self):
|
|||
value1 = new CNTK::NDArrayViewPtr();
|
||||
}
|
||||
|
||||
PyObject* second = PyTuple_GET_ITEM(value, 1);
|
||||
PyObject* second = PyTuple_GET_ITEM(value, 1);
|
||||
void *raw_value2 = 0;
|
||||
int res2 = SWIG_ConvertPtr(second, &raw_value2, SWIGTYPE_p_std__shared_ptrT_CNTK__NDArrayView_t, 0);
|
||||
if (!SWIG_IsOK(res2)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res2), "cannot convert value of dictionary to CNTK::NDArrayViewPtr");
|
||||
SWIG_exception_fail(SWIG_ArgError(res2), "cannot convert value of dictionary to CNTK::NDArrayViewPtr");
|
||||
}
|
||||
|
||||
CNTK::NDArrayViewPtr* value2;
|
||||
|
@ -464,7 +665,7 @@ def dynamic_axes(self):
|
|||
args_map.insert(std::make_pair(*var, std::make_pair(*value1, *value2)));
|
||||
} else {
|
||||
SWIG_exception(SWIG_TypeError, "tuple expected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$1 = &args_map;
|
||||
|
@ -509,7 +710,7 @@ def dynamic_axes(self):
|
|||
void *cntk_key = 0 ;
|
||||
int res = SWIG_ConvertPtr(py_key, &cntk_key, SWIGTYPE_p_CNTK__StreamInformation, 0);
|
||||
if (!SWIG_IsOK(res)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res), "cannot convert key of dictionary to CNTK::StreamInformation");
|
||||
SWIG_exception_fail(SWIG_ArgError(res), "cannot convert key of dictionary to CNTK::StreamInformation");
|
||||
}
|
||||
if (!cntk_key) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "invalid null reference when converting key of dictionary to CNTK::StreamInformation");
|
||||
|
@ -547,7 +748,7 @@ def dynamic_axes(self):
|
|||
void *raw_var = 0 ;
|
||||
int res1 = SWIG_ConvertPtr(key, &raw_var, SWIGTYPE_p_CNTK__Parameter, 0);
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert key of dictionary to CNTK::Parameter");
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert key of dictionary to CNTK::Parameter");
|
||||
}
|
||||
if (!raw_var) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "invalid null reference when converting key of dictionary to CNTK::Parameter");
|
||||
|
@ -558,7 +759,7 @@ def dynamic_axes(self):
|
|||
void *raw_value = 0;
|
||||
int res2 = SWIG_ConvertPtr(value, &raw_value, SWIGTYPE_p_std__shared_ptrT_CNTK__NDArrayView_t, 0);
|
||||
if (!SWIG_IsOK(res2)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res2), "cannot convert value of dictionary to CNTK::NDArrayViewPtr");
|
||||
SWIG_exception_fail(SWIG_ArgError(res2), "cannot convert value of dictionary to CNTK::NDArrayViewPtr");
|
||||
}
|
||||
|
||||
CNTK::NDArrayViewPtr* value;
|
||||
|
@ -595,14 +796,14 @@ def dynamic_axes(self):
|
|||
|
||||
PyObject *iterator = PyObject_GetIter($input);
|
||||
if (iterator == NULL) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert list element to CNTK::DictionaryValue");
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert list element to CNTK::DictionaryValue");
|
||||
}
|
||||
|
||||
while ((item = PyIter_Next(iterator))) {
|
||||
void *raw_var = 0 ;
|
||||
int res1 = SWIG_ConvertPtr(item, &raw_var, SWIGTYPE_p_CNTK__DictionaryValue, 0);
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert list element to CNTK::DictionaryValue");
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert list element to CNTK::DictionaryValue");
|
||||
}
|
||||
if (!raw_var) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "invalid null reference when converting a list element to CNTK::DictionaryValue");
|
||||
|
@ -618,7 +819,7 @@ def dynamic_axes(self):
|
|||
Py_DECREF(iterator);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert list element to CNTK::DictionaryValue");
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert list element to CNTK::DictionaryValue");
|
||||
}
|
||||
|
||||
$1 = vec;
|
||||
|
@ -642,7 +843,7 @@ def dynamic_axes(self):
|
|||
}
|
||||
|
||||
%typemap(in) std::unordered_set<CNTK::Variable>& (
|
||||
std::unordered_set<CNTK::Variable> args_set
|
||||
std::unordered_set<CNTK::Variable> args_set
|
||||
) {
|
||||
if (PySet_Check($input)) {
|
||||
|
||||
|
@ -650,14 +851,14 @@ def dynamic_axes(self):
|
|||
|
||||
PyObject *iterator = PyObject_GetIter($input);
|
||||
if (iterator == NULL) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert list element to CNTK::Variable");
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert list element to CNTK::Variable");
|
||||
}
|
||||
|
||||
while ((item = PyIter_Next(iterator))) {
|
||||
void *raw_var = 0 ;
|
||||
int res1 = SWIG_ConvertPtr(item, &raw_var, SWIGTYPE_p_CNTK__Variable, 0);
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert set element to CNTK::Variable");
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert set element to CNTK::Variable");
|
||||
}
|
||||
if (!raw_var) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "invalid null reference when converting a list element to CNTK::Variable");
|
||||
|
@ -673,7 +874,7 @@ def dynamic_axes(self):
|
|||
Py_DECREF(iterator);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert set element to CNTK::Variable");
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert set element to CNTK::Variable");
|
||||
}
|
||||
|
||||
$1 = &args_set;
|
||||
|
@ -693,7 +894,7 @@ def dynamic_axes(self):
|
|||
}
|
||||
|
||||
%typemap(in) std::unordered_set<CNTK::StreamInformation>& (
|
||||
std::unordered_set<CNTK::StreamInformation> args_set
|
||||
std::unordered_set<CNTK::StreamInformation> args_set
|
||||
) {
|
||||
if (PySet_Check($input)) {
|
||||
|
||||
|
@ -701,14 +902,14 @@ def dynamic_axes(self):
|
|||
|
||||
PyObject *iterator = PyObject_GetIter($input);
|
||||
if (iterator == NULL) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert list element to CNTK::StreamInformation");
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert list element to CNTK::StreamInformation");
|
||||
}
|
||||
|
||||
while ((item = PyIter_Next(iterator))) {
|
||||
void *raw_var = 0 ;
|
||||
int res1 = SWIG_ConvertPtr(item, &raw_var, SWIGTYPE_p_CNTK__StreamInformation, 0);
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert set element to CNTK::StreamInformation");
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert set element to CNTK::StreamInformation");
|
||||
}
|
||||
if (!raw_var) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "invalid null reference when converting a set element to CNTK::StreamInformation");
|
||||
|
@ -724,7 +925,7 @@ def dynamic_axes(self):
|
|||
Py_DECREF(iterator);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert set element to CNTK::StreamInformation");
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert set element to CNTK::StreamInformation");
|
||||
}
|
||||
|
||||
$1 = &args_set;
|
||||
|
@ -744,7 +945,7 @@ def dynamic_axes(self):
|
|||
}
|
||||
|
||||
%typemap(in) std::unordered_set<CNTK::Parameter>& (
|
||||
std::unordered_set<CNTK::Parameter> args_set
|
||||
std::unordered_set<CNTK::Parameter> args_set
|
||||
) {
|
||||
if (PyList_Check($input)) {
|
||||
|
||||
|
@ -752,14 +953,14 @@ def dynamic_axes(self):
|
|||
|
||||
PyObject *iterator = PyObject_GetIter($input);
|
||||
if (iterator == NULL) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert list element to CNTK::Parameter");
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert list element to CNTK::Parameter");
|
||||
}
|
||||
|
||||
while ((item = PyIter_Next(iterator))) {
|
||||
void *raw_var = 0 ;
|
||||
int res1 = SWIG_ConvertPtr(item, &raw_var, SWIGTYPE_p_CNTK__Parameter, 0);
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert set element to CNTK::Parameter");
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert set element to CNTK::Parameter");
|
||||
}
|
||||
if (!raw_var) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "invalid null reference when converting a list element to CNTK::Parameter");
|
||||
|
@ -775,7 +976,7 @@ def dynamic_axes(self):
|
|||
Py_DECREF(iterator);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert set element to CNTK::Parameter");
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert set element to CNTK::Parameter");
|
||||
}
|
||||
|
||||
$1 = &args_set;
|
||||
|
@ -796,7 +997,7 @@ def dynamic_axes(self):
|
|||
}
|
||||
|
||||
%typemap(in) std::unordered_set<CNTK::LearnerPtr>& (
|
||||
std::unordered_set<CNTK::LearnerPtr> args_set
|
||||
std::unordered_set<CNTK::LearnerPtr> args_set
|
||||
) {
|
||||
if (PyList_Check($input)) {
|
||||
|
||||
|
@ -804,14 +1005,14 @@ def dynamic_axes(self):
|
|||
|
||||
PyObject *iterator = PyObject_GetIter($input);
|
||||
if (iterator == NULL) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert list element to CNTK::LearnerPtr");
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert list element to CNTK::LearnerPtr");
|
||||
}
|
||||
|
||||
while ((item = PyIter_Next(iterator))) {
|
||||
void *raw_var = 0 ;
|
||||
int res1 = SWIG_ConvertPtr(item, &raw_var, SWIGTYPE_p_std__shared_ptrT_CNTK__Learner_t, 0);
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert list element to CNTK::LearnerPtr");
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert list element to CNTK::LearnerPtr");
|
||||
}
|
||||
if (!raw_var) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "invalid null reference when converting a list element to CNTK::LearnerPtr");
|
||||
|
@ -827,7 +1028,7 @@ def dynamic_axes(self):
|
|||
Py_DECREF(iterator);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert list element to CNTK::LearnerPtr");
|
||||
SWIG_exception_fail(SWIG_ValueError, "cannot convert list element to CNTK::LearnerPtr");
|
||||
}
|
||||
|
||||
$1 = &args_set;
|
||||
|
@ -845,7 +1046,7 @@ def dynamic_axes(self):
|
|||
|
||||
|
||||
%typemap(in) std::unordered_map<CNTK::Variable, CNTK::Variable>& (
|
||||
std::unordered_map<CNTK::Variable, CNTK::Variable> args_map
|
||||
std::unordered_map<CNTK::Variable, CNTK::Variable> args_map
|
||||
) {
|
||||
if (PyDict_Check($input)) {
|
||||
|
||||
|
@ -856,7 +1057,7 @@ def dynamic_axes(self):
|
|||
void *raw_var = 0 ;
|
||||
int res1 = SWIG_ConvertPtr(key, &raw_var, SWIGTYPE_p_CNTK__Variable, 0);
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert key of dictionary to CNTK::Variable");
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "cannot convert key of dictionary to CNTK::Variable");
|
||||
}
|
||||
if (!raw_var) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "invalid null reference when converting key of dictionary to CNTK::Variable");
|
||||
|
@ -867,7 +1068,7 @@ def dynamic_axes(self):
|
|||
void *raw_value = 0;
|
||||
int res2 = SWIG_ConvertPtr(value, &raw_value, SWIGTYPE_p_CNTK__Variable, 0);
|
||||
if (!SWIG_IsOK(res2)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res2), "cannot convert value of dictionary to CNTK::Variable");
|
||||
SWIG_exception_fail(SWIG_ArgError(res2), "cannot convert value of dictionary to CNTK::Variable");
|
||||
}
|
||||
|
||||
CNTK::Variable* value;
|
||||
|
@ -903,9 +1104,9 @@ def dynamic_axes(self):
|
|||
{
|
||||
SWIG_exception(SWIG_RuntimeError, "error passing set to Python");
|
||||
}
|
||||
|
||||
|
||||
// *&$1 -> $1 is the returned result being converted (unordered_set<...>*),
|
||||
// wrapped by SwigValueWrapper. So we need to unwrap it using '&',
|
||||
// wrapped by SwigValueWrapper. So we need to unwrap it using '&',
|
||||
// then access its value using '*'.
|
||||
for (auto var : *&$1)
|
||||
{
|
||||
|
@ -918,7 +1119,7 @@ def dynamic_axes(self):
|
|||
$result = container;
|
||||
}
|
||||
%enddef
|
||||
|
||||
|
||||
%unordered_set_conversion(Variable, SWIGTYPE_p_CNTK__Variable)
|
||||
%unordered_set_conversion(Constant, SWIGTYPE_p_CNTK__Constant)
|
||||
%unordered_set_conversion(Parameter, SWIGTYPE_p_CNTK__Parameter)
|
||||
|
@ -932,7 +1133,7 @@ def dynamic_axes(self):
|
|||
{
|
||||
SWIG_exception(SWIG_RuntimeError, "error passing set to Python");
|
||||
}
|
||||
|
||||
|
||||
for (auto var : *$1)
|
||||
{
|
||||
PyObject *item = SWIG_NewPointerObj(new CNTK::DATA_TYPE(var), _SWIG_TYPE, SWIG_POINTER_OWN );
|
||||
|
@ -960,16 +1161,16 @@ def dynamic_axes(self):
|
|||
{
|
||||
SWIG_exception(SWIG_RuntimeError, "error passing dictionary to Python");
|
||||
}
|
||||
|
||||
|
||||
// *&$1 -> $1 is the returned result being converted (unordered_map<...>*),
|
||||
// wrapped by SwigValueWrapper. So we need to unwrap it using '&',
|
||||
// wrapped by SwigValueWrapper. So we need to unwrap it using '&',
|
||||
// then access its value using '*'.
|
||||
for (auto it : *$1)
|
||||
{
|
||||
{
|
||||
PyObject *returned_var = SWIG_NewPointerObj(SWIG_as_voidptr(new CNTK::DATA_TYPE1(it.first)), _SWIG_TYPE1, SWIG_POINTER_OWN);
|
||||
PyObject *returned_val = SWIG_NewPointerObj(SWIG_as_voidptr(new CNTK::DATA_TYPE2(it.second)), _SWIG_TYPE2, SWIG_POINTER_OWN);
|
||||
|
||||
PyDict_SetItem(container, returned_var, returned_val);
|
||||
|
||||
PyDict_SetItem(container, returned_var, returned_val);
|
||||
|
||||
Py_DECREF(returned_var);
|
||||
Py_DECREF(returned_val);
|
||||
|
@ -1024,7 +1225,7 @@ def dynamic_axes(self):
|
|||
}
|
||||
|
||||
void* buffer = const_cast<void*>(reinterpret_cast<const void*>(cpuMask->DataBuffer()));
|
||||
|
||||
|
||||
PyObject* ndarray = PyArray_SimpleNew(dimensions.size(), shape, NPY_BYTE);
|
||||
void *arr_data = PyArray_DATA((PyArrayObject*)ndarray);
|
||||
|
||||
|
@ -1046,20 +1247,20 @@ def dynamic_axes(self):
|
|||
//
|
||||
%extend CNTK::NDArrayView {
|
||||
|
||||
NDArrayView(PyObject* pyobj, const CNTK::DeviceDescriptor& device, bool readOnly)
|
||||
NDArrayView(PyObject* pyobj, const CNTK::DeviceDescriptor& device, bool readOnly)
|
||||
{
|
||||
if (!PyArray_Check((PyArrayObject*)pyobj))
|
||||
{
|
||||
// Note that in contrast to numpy.i's implementation we demand NumPy arrays
|
||||
// Note that in contrast to numpy.i's implementation we demand NumPy arrays
|
||||
// and do not accept arbitrary sequences, which would needed to be copied around.
|
||||
throw std::logic_error("NumPy array expected");
|
||||
}
|
||||
|
||||
PyArrayObject* array = (PyArrayObject*)pyobj;
|
||||
|
||||
int rank = PyArray_NDIM(array);
|
||||
|
||||
npy_intp* np_shape = PyArray_SHAPE(array);
|
||||
int rank = PyArray_NDIM(array);
|
||||
|
||||
npy_intp* np_shape = PyArray_SHAPE(array);
|
||||
std::vector<size_t> shape;
|
||||
|
||||
npy_intp num_elements = 1;
|
||||
|
@ -1067,11 +1268,11 @@ def dynamic_axes(self):
|
|||
for (int i=rank-1; i>=0; i--)
|
||||
{
|
||||
shape.push_back(np_shape[i]);
|
||||
num_elements *= np_shape[i];
|
||||
num_elements *= np_shape[i];
|
||||
}
|
||||
|
||||
int typecode = PyArray_TYPE(array);
|
||||
|
||||
|
||||
NDArrayView* view;
|
||||
if (typecode == NPY_FLOAT)
|
||||
{
|
||||
|
@ -1094,68 +1295,8 @@ def dynamic_axes(self):
|
|||
}
|
||||
|
||||
PyObject* to_numpy() {
|
||||
if ((*self).GetStorageFormat() != StorageFormat::Dense)
|
||||
throw std::invalid_argument("only dense supported at the moment");
|
||||
|
||||
// FIXME use not yet existing NDShape function that returns the dimensions at once
|
||||
std::vector<size_t> dimensions_cntk = (*self).Shape().Dimensions();
|
||||
std::vector<size_t> dimensions;
|
||||
|
||||
// We have at least one element. In case the shape is empty (e.g.
|
||||
// '()'), we have a scalar, which we need to copy (e.g. a constant).
|
||||
size_t num_elements = 1;
|
||||
|
||||
// CNTK uses column major, thus we reverse the shape
|
||||
for (int i=dimensions_cntk.size()-1; i>=0; i--)
|
||||
{
|
||||
dimensions.push_back(dimensions_cntk[i]);
|
||||
num_elements *= dimensions_cntk[i];
|
||||
}
|
||||
|
||||
npy_intp* shape = reinterpret_cast<npy_intp*>(&dimensions[0]);
|
||||
|
||||
CNTK::DataType cntk_type = (*self).GetDataType();
|
||||
|
||||
NDArrayView* cpuView;
|
||||
if ((*self).Device() != DeviceDescriptor::CPUDevice())
|
||||
{
|
||||
cpuView = new NDArrayView(cntk_type, (*self).Shape(), DeviceDescriptor::CPUDevice());
|
||||
cpuView->CopyFrom((*self));
|
||||
}
|
||||
else
|
||||
{
|
||||
cpuView = &(*self);
|
||||
}
|
||||
|
||||
NPY_TYPES numpy_type;
|
||||
void* buffer;
|
||||
|
||||
if (cntk_type == CNTK::DataType::Float)
|
||||
{
|
||||
numpy_type = NPY_FLOAT;
|
||||
buffer = (void*)cpuView->DataBuffer<float>();
|
||||
}
|
||||
else if (cntk_type == CNTK::DataType::Double)
|
||||
{
|
||||
numpy_type = NPY_DOUBLE;
|
||||
buffer = (void*)cpuView->DataBuffer<double>();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::invalid_argument("unknown CNTK data type");
|
||||
}
|
||||
|
||||
PyObject* ndarray = PyArray_SimpleNew(dimensions.size(), shape, numpy_type);
|
||||
void *arr_data = PyArray_DATA((PyArrayObject*)ndarray);
|
||||
|
||||
memcpy(arr_data, buffer, PyArray_ITEMSIZE((PyArrayObject*) ndarray) * num_elements);
|
||||
|
||||
if ((*self).Device() != DeviceDescriptor::CPUDevice())
|
||||
{
|
||||
delete cpuView;
|
||||
}
|
||||
|
||||
return ndarray;
|
||||
PyObject *NDArrayViewToNumPy(const CNTK::NDArrayView*);
|
||||
return NDArrayViewToNumPy(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1240,7 +1381,7 @@ StreamInformation.__eq__ = lambda a,b: a.m_name==b.m_name and a.m_id==b.m_id and
|
|||
%pythoncode %{
|
||||
# in case of multiple outputs return the function, not the variable
|
||||
def get_output_and_keep_reference(self):
|
||||
variable = self._output()
|
||||
variable = self._output()
|
||||
variable.__owner = self
|
||||
return variable
|
||||
Function.output = lambda self:get_output_and_keep_reference(self)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
# Licensed under the MIT license. See LICENSE.md file in the project root
|
||||
# for full license information.
|
||||
# ==============================================================================
|
|
@ -27,7 +27,7 @@ def test_text_format():
|
|||
|
||||
mb_source = text_format_minibatch_source(path, [
|
||||
StreamConfiguration( 'features', input_dim, True, 'x' ),
|
||||
StreamConfiguration( 'labels', num_output_classes, False, 'y')], 0)
|
||||
StreamConfiguration( 'labels', num_output_classes, False, 'y')])
|
||||
assert isinstance(mb_source, MinibatchSource)
|
||||
|
||||
features_si = mb_source.stream_info('features')
|
||||
|
@ -36,11 +36,11 @@ def test_text_format():
|
|||
mb = mb_source.get_next_minibatch(7)
|
||||
|
||||
features = mb[features_si].m_data
|
||||
# 2 samples, max seq len 4, 1000 dim
|
||||
assert features.data().shape().dimensions() == (2, 4, input_dim)
|
||||
assert features.data().is_sparse()
|
||||
# TODO features is sparse and cannot be accessed right now:
|
||||
# *** RuntimeError: DataBuffer/WritableDataBuffer methods can only be called for NDArrayiew objects with dense storage format
|
||||
# 2 samples, max seq len 4, 1000 dim
|
||||
#assert features.data().shape().dimensions() == (2, 4, input_dim)
|
||||
#assert features.data().is_sparse()
|
||||
|
||||
labels = mb[labels_si].m_data
|
||||
# 2 samples, max seq len 1, 5 dim
|
||||
|
|
|
@ -1810,14 +1810,14 @@ from cntk.axis import Axis
|
|||
|
||||
|
||||
@typemap
|
||||
def input_variable(shape, data_type=np.float32, needs_gradient=True, is_sparse=False,
|
||||
dynamic_axes=Axis.default_input_variable_dynamic_axes, name=''):
|
||||
def input_variable(shape, dtype=np.float32, needs_gradient=True, is_sparse=False,
|
||||
dynamic_axes=Axis.default_input_variable_dynamic_axes(), name=''):
|
||||
'''
|
||||
It creates an input node.
|
||||
|
||||
Args:
|
||||
shape (`tuple` or `int`): the shape of the input tensor
|
||||
data_type (`type`, optional): np.float32 (default) or np.float64
|
||||
dtype (`type`, optional): np.float32 (default) or np.float64
|
||||
needs_gradients (`bool`, optional): whether to back-propagates to it or not. True by default.
|
||||
is_sparse (`bool`, optional): whether the variable is sparse (`False` by default)
|
||||
dynamic_axes (`list` or `tuple`, default): a list of dynamic axis (e.g., batch axis, time axis)
|
||||
|
@ -1831,9 +1831,9 @@ def input_variable(shape, data_type=np.float32, needs_gradient=True, is_sparse=F
|
|||
|
||||
shape = sanitize_shape(shape)
|
||||
|
||||
if data_type is None:
|
||||
data_type = np.float32
|
||||
dtype = sanitize_dtype_cntk(data_type)
|
||||
if dtype is None:
|
||||
dtype = np.float32
|
||||
dtype = sanitize_dtype_cntk(dtype)
|
||||
dynamic_axes = sanitize_dynamic_axes(dynamic_axes)
|
||||
|
||||
# TODO dynamic axis for numpy arrays
|
||||
|
@ -1863,7 +1863,7 @@ def placeholder_variable(shape=None, dynamic_axes=None, name=''):
|
|||
shape = sanitize_shape(shape)
|
||||
|
||||
if dynamic_axes is None:
|
||||
dynamic_axes = Axis.unknown_dynamic_axes
|
||||
dynamic_axes = Axis.unknown_dynamic_axes()
|
||||
|
||||
dynamic_axes = sanitize_dynamic_axes(dynamic_axes)
|
||||
return placeholder_variable(shape, name, dynamic_axes)
|
||||
|
|
|
@ -51,7 +51,7 @@ def test_op_convolution_without_padding(convolution_map, convolution_input, devi
|
|||
backward = AA([[conv_map]])
|
||||
|
||||
a = I(shape=conv_input.shape,
|
||||
data_type=sanitize_dtype_cntk(precision),
|
||||
dtype=sanitize_dtype_cntk(precision),
|
||||
needs_gradient=True,
|
||||
name='a')
|
||||
|
||||
|
@ -93,7 +93,7 @@ def test_op_avg_pooling(input_size, pooling_window, strides, result, device_id,
|
|||
input_operand = x.reshape(input_size)
|
||||
|
||||
a = I(shape=input_operand.shape,
|
||||
data_type=sanitize_dtype_cntk(precision),
|
||||
dtype=sanitize_dtype_cntk(precision),
|
||||
needs_gradient=True,
|
||||
name='a')
|
||||
|
||||
|
@ -137,7 +137,7 @@ def test_op_max_pooling(input_size, pooling_window, strides, result, device_id,
|
|||
input_operand = x.reshape(input_size)
|
||||
|
||||
a = I(shape=input_operand.shape,
|
||||
data_type=sanitize_dtype_cntk(precision),
|
||||
dtype=sanitize_dtype_cntk(precision),
|
||||
needs_gradient=True,
|
||||
name='a')
|
||||
|
||||
|
|
|
@ -86,12 +86,12 @@ def test_op_plus_var_sequences_input_input(left_batch, right_batch, device_id, p
|
|||
right_shape = right_value[0][0].shape
|
||||
|
||||
a = I(shape=left_shape,
|
||||
data_type=sanitize_dtype_cntk(PRECISION_TO_TYPE[precision]),
|
||||
dtype=sanitize_dtype_cntk(PRECISION_TO_TYPE[precision]),
|
||||
needs_gradient=True,
|
||||
name='a')
|
||||
|
||||
b = I(shape=right_shape,
|
||||
data_type=sanitize_dtype_cntk(PRECISION_TO_TYPE[precision]),
|
||||
dtype=sanitize_dtype_cntk(PRECISION_TO_TYPE[precision]),
|
||||
needs_gradient=True,
|
||||
name='b')
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ def test_op_dropout(shape, dropout_rate, device_id, precision):
|
|||
value = np.ones(shape=shape, dtype=PRECISION_TO_TYPE[precision])
|
||||
|
||||
a = I(shape=value.shape,
|
||||
data_type=sanitize_dtype_cntk(PRECISION_TO_TYPE[precision]),
|
||||
dtype=sanitize_dtype_cntk(PRECISION_TO_TYPE[precision]),
|
||||
needs_gradient=True,
|
||||
name='a')
|
||||
|
||||
|
@ -168,7 +168,7 @@ def test_op_dropout_bad_input(dropout_rate):
|
|||
from cntk import dropout
|
||||
from cntk.utils import eval, sanitize_dtype_cntk, cntk_device
|
||||
|
||||
a = I(shape=(1, 2), data_type='float', needs_gradient=True, name='a')
|
||||
a = I(shape=(1, 2), dtype='float', needs_gradient=True, name='a')
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
dropout_node = dropout(a, dropout_rate=dropout_rate)
|
||||
|
|
|
@ -37,7 +37,7 @@ def _test_unary_op(precision, device_id, op_func,
|
|||
value = AA(value, dtype=PRECISION_TO_TYPE[precision])
|
||||
|
||||
a = I(shape=value.shape,
|
||||
data_type=sanitize_dtype_cntk(PRECISION_TO_TYPE[precision]),
|
||||
dtype=sanitize_dtype_cntk(PRECISION_TO_TYPE[precision]),
|
||||
needs_gradient=True,
|
||||
name='a')
|
||||
|
||||
|
@ -66,12 +66,12 @@ def _test_binary_op(precision, device_id, op_func, left_operand, right_operand,
|
|||
right_value = AA(right_operand, dtype=PRECISION_TO_TYPE[precision])
|
||||
|
||||
a = I(shape=left_value.shape,
|
||||
data_type=sanitize_dtype_cntk(precision),
|
||||
dtype=sanitize_dtype_cntk(precision),
|
||||
needs_gradient=True,
|
||||
name='a')
|
||||
|
||||
b = I(shape=right_value.shape,
|
||||
data_type=sanitize_dtype_cntk(precision),
|
||||
dtype=sanitize_dtype_cntk(precision),
|
||||
needs_gradient=True,
|
||||
name='b')
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ def test_op_future_value(tensor_number_of_values, input_size, time_step, initial
|
|||
np.put(backward, range(total_elements - elements_to_roll), 0.0)
|
||||
|
||||
a = I(shape=x.shape[1:],
|
||||
data_type=sanitize_dtype_cntk(precision),
|
||||
dtype=sanitize_dtype_cntk(precision),
|
||||
needs_gradient=True,
|
||||
name='a')
|
||||
|
||||
|
@ -71,7 +71,7 @@ def test_op_past_value(tensor_number_of_values, input_size, time_step, initial_s
|
|||
expected_forward = AA([x_rolled])
|
||||
|
||||
a = I(shape=x.shape[1:],
|
||||
data_type=sanitize_dtype_cntk(precision),
|
||||
dtype=sanitize_dtype_cntk(precision),
|
||||
needs_gradient=True,
|
||||
name='a')
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# ==============================================================================
|
||||
|
||||
"""
|
||||
Unit tests for reshaping operations.
|
||||
Unit tests for reshaping operations.
|
||||
"""
|
||||
|
||||
from __future__ import division
|
||||
|
@ -52,7 +52,7 @@ def test_op_reshape(input_shape, output_shape, expected_output_shape, device_id,
|
|||
input_reshaped = input_tensor.reshape(expected_output_shape)
|
||||
|
||||
a = I(shape=input_tensor.shape,
|
||||
data_type=sanitize_dtype_cntk(PRECISION_TO_TYPE[precision]),
|
||||
dtype=sanitize_dtype_cntk(PRECISION_TO_TYPE[precision]),
|
||||
needs_gradient=True,
|
||||
name='a')
|
||||
|
||||
|
@ -94,7 +94,7 @@ def test_op_slice(input_data, slice_params, expected_result, device_id, precisio
|
|||
|
||||
input_data = AA(input_data, dtype=PRECISION_TO_TYPE[precision])
|
||||
a = I(shape=input_data.shape,
|
||||
data_type=sanitize_dtype_cntk(PRECISION_TO_TYPE[precision]),
|
||||
dtype=sanitize_dtype_cntk(PRECISION_TO_TYPE[precision]),
|
||||
needs_gradient=True,
|
||||
name='a')
|
||||
|
||||
|
@ -161,7 +161,7 @@ def test_op_slice_sequence(input_data, slice_params, expected_result, device_id,
|
|||
t = Axis.new_unique_dynamic_axis('t')
|
||||
sample_shape = input_data.shape[1:]
|
||||
a = I(shape=sample_shape,
|
||||
data_type=sanitize_dtype_cntk(PRECISION_TO_TYPE[precision]),
|
||||
dtype=sanitize_dtype_cntk(PRECISION_TO_TYPE[precision]),
|
||||
needs_gradient=True,
|
||||
dynamic_axes=[Axis.default_batch_axis(), t],
|
||||
name='a')
|
||||
|
@ -215,11 +215,11 @@ def test_op_splice(input_data1, input_data2, axis, expected_result, device_id, p
|
|||
input_data1 = AA(input_data1, dtype=PRECISION_TO_TYPE[precision])
|
||||
input_data2 = AA(input_data2, dtype=PRECISION_TO_TYPE[precision])
|
||||
a = I(shape=input_data1.shape,
|
||||
data_type=sanitize_dtype_cntk(PRECISION_TO_TYPE[precision]),
|
||||
dtype=sanitize_dtype_cntk(PRECISION_TO_TYPE[precision]),
|
||||
needs_gradient=True,
|
||||
name='a')
|
||||
b = I(shape=input_data2.shape,
|
||||
data_type=sanitize_dtype_cntk(PRECISION_TO_TYPE[precision]),
|
||||
dtype=sanitize_dtype_cntk(PRECISION_TO_TYPE[precision]),
|
||||
needs_gradient=True,
|
||||
name='b')
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ class Variable(VariableMixin, TensorOpsMixin, cntk_py.Variable):
|
|||
|
||||
Args:
|
||||
shape (`tuple`): the shape of this variable.
|
||||
data_type (`np.float32 or np.float64`): data type of the values that will be bound to this variable.
|
||||
dtype (`np.float32 or np.float64`): data type of the values that will be bound to this variable.
|
||||
Default is np.float32
|
||||
needs_gradient (`bool`): if set to True any expression that contains this variable
|
||||
will also be differentiated with respect to this variable.
|
||||
|
@ -119,16 +119,16 @@ class Variable(VariableMixin, TensorOpsMixin, cntk_py.Variable):
|
|||
express dimensions that can vary across examples or minibatches.
|
||||
name(`str`): an optional name for this parameter.
|
||||
'''
|
||||
def __init__(self, shape=None, data_type=None, needs_gradient=False, is_sparse=False,
|
||||
def __init__(self, shape=None, dtype=None, needs_gradient=False, is_sparse=False,
|
||||
dynamic_axes=[cntk_py.Axis.default_dynamic_axis(), cntk_py.Axis.default_batch_axis()], name=''):
|
||||
shape = utils.sanitize_shape(shape)
|
||||
|
||||
if data_type is None:
|
||||
data_type = np.float32
|
||||
dtype = utils.sanitize_dtype_cntk(data_type)
|
||||
if dtype is None:
|
||||
dtype = np.float32
|
||||
dtype = utils.sanitize_dtype_cntk(dtype)
|
||||
|
||||
super().__init__(shape, is_sparse, dtype, needs_gradient, name,
|
||||
dynamic_axes)
|
||||
dynamic_axes)
|
||||
|
||||
|
||||
class Parameter(VariableMixin, TensorOpsMixin, cntk_py.Parameter):
|
||||
|
@ -176,7 +176,7 @@ class Parameter(VariableMixin, TensorOpsMixin, cntk_py.Parameter):
|
|||
'''
|
||||
NumPy array of the value
|
||||
'''
|
||||
return super().value().to_numpy()
|
||||
return super().value().to_numpy()
|
||||
|
||||
class Constant(VariableMixin, TensorOpsMixin, cntk_py.Constant):
|
||||
'''
|
||||
|
@ -188,7 +188,7 @@ class Constant(VariableMixin, TensorOpsMixin, cntk_py.Constant):
|
|||
Args:
|
||||
value (`np.ndarray` or `list` or `float` or `int`): Initial value.
|
||||
BUGBUG: Document initializers
|
||||
data_type (`np.float32` or `np.float64`): data type to store the values as.
|
||||
dtype (`np.float32` or `np.float64`): data type to store the values as.
|
||||
device (:class:`cntk.device.DeviceDescriptor`): the device on which the values should reside.
|
||||
name (`str`): an optional name for this constant.
|
||||
'''
|
||||
|
@ -204,7 +204,7 @@ class Constant(VariableMixin, TensorOpsMixin, cntk_py.Constant):
|
|||
super().__init__(utils.sanitize_shape(shape), sanitize_dtype_cntk(dtype), value)
|
||||
else:
|
||||
ndav = sanitize_value(shape, value, dtype, device)
|
||||
super().__init__(ndav, name)
|
||||
super().__init__(ndav, name)
|
||||
|
||||
|
||||
@property
|
||||
|
@ -212,5 +212,5 @@ class Constant(VariableMixin, TensorOpsMixin, cntk_py.Constant):
|
|||
'''
|
||||
NumPy array of the value
|
||||
'''
|
||||
return super().value().to_numpy()
|
||||
return super().value().to_numpy()
|
||||
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
# Copyright (c) Microsoft. All rights reserved.
|
||||
# Licensed under the MIT license. See LICENSE.md file in the project root
|
||||
# for full license information.
|
||||
# ==============================================================================
|
||||
|
||||
import cntk as C
|
||||
import numpy as np
|
||||
|
||||
def _check(expected, d):
|
||||
for key in expected:
|
||||
assert key in d
|
||||
assert d[key] == expected[key]
|
||||
for key in d:
|
||||
assert key in expected
|
||||
|
||||
def test_convolution_attributes():
|
||||
x = C.input_variable( (1, 5, 5) )
|
||||
filter = np.reshape(np.array([2, -1, -1, 2], dtype = np.float32), (1, 2, 2))
|
||||
kernel = C.constant(value = filter)
|
||||
f = C.convolution(kernel , x, auto_padding = [False])
|
||||
d = f.root_function.attributes
|
||||
expected = {'autoPadding': [False, False, False],
|
||||
'sharing': [True, True, True],
|
||||
'strides': (1, 1, 1),
|
||||
'maxTempMemSizeInSamples': 0,
|
||||
'upperPad': (0, 0, 0),
|
||||
'lowerPad': (0, 0, 0),
|
||||
'transpose': False
|
||||
}
|
||||
_check(expected, d)
|
||||
|
||||
def test_dropout_attributes():
|
||||
x = C.input_variable( (1, 5, 5) )
|
||||
f = C.dropout(x, 0.5)
|
||||
d = f.root_function.attributes
|
||||
expected = {'dropoutRate': 0.5}
|
||||
_check(expected, d)
|
||||
|
||||
def test_slice_attributes():
|
||||
x = C.input_variable((2,3))
|
||||
f = C.slice(x, 0, 1, 2)
|
||||
d = f.root_function.attributes
|
||||
expected = {'endIndex': 2, 'beginIndex': 1, 'axis': ('ordered', 'static', 1)}
|
||||
_check(expected, d)
|
|
@ -670,7 +670,7 @@ def sanitize_axis(axis):
|
|||
|
||||
|
||||
def sanitize_dynamic_axes(axes):
|
||||
if axes is not cntk_py.Axis.default_input_variable_dynamic_axes:
|
||||
if axes != cntk_py.Axis.default_input_variable_dynamic_axes():
|
||||
if not type(axes) in (list, tuple):
|
||||
axes = [axes]
|
||||
else:
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
# Licensed under the MIT license. See LICENSE.md file in the project root
|
||||
# for full license information.
|
||||
# ==============================================================================
|
|
@ -154,7 +154,7 @@ cntk_module = Extension(
|
|||
# Do not include examples
|
||||
packages = [x for x in find_packages() if x.startswith('cntk') and not x.startswith('cntk.swig')]
|
||||
|
||||
package_data = { 'cntk': ['pytest.ini'] }
|
||||
package_data = { 'cntk': ['pytest.ini', 'io/tests/tf_data.txt'] }
|
||||
|
||||
if IS_WINDOWS:
|
||||
# On Windows copy all runtime libs to the base folder of Python
|
||||
|
|
Загрузка…
Ссылка в новой задаче