Integrate gaizna/eval_unittests into master
This commit is contained in:
Коммит
b519e5de40
16
CNTK.sln
16
CNTK.sln
|
@ -1270,6 +1270,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FullUtterance", "FullUttera
|
|||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Truncated", "Truncated", "{1141DC61-E014-4DEC-9157-F6B1FC055C7A}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EvalTests", "Tests\UnitTests\EvalTests\EvalTests.vcxproj", "{82125DA1-1CD7-45B5-9281-E6AE7C287CB7}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{60BDB847-D0C4-4FD3-A947-0C15C08BCDB5} = {60BDB847-D0C4-4FD3-A947-0C15C08BCDB5}
|
||||
{86883653-8A61-4038-81A0-2379FAE4200A} = {86883653-8A61-4038-81A0-2379FAE4200A}
|
||||
{482999D1-B7E2-466E-9F8D-2119F93EAFD9} = {482999D1-B7E2-466E-9F8D-2119F93EAFD9}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug_CpuOnly|x64 = Debug_CpuOnly|x64
|
||||
|
@ -1516,6 +1523,14 @@ Global
|
|||
{578D52A0-3928-4405-A016-F016E8B49031}.Release_CpuOnly|x64.Build.0 = Release_CpuOnly|x64
|
||||
{578D52A0-3928-4405-A016-F016E8B49031}.Release|x64.ActiveCfg = Release|x64
|
||||
{578D52A0-3928-4405-A016-F016E8B49031}.Release|x64.Build.0 = Release|x64
|
||||
{82125DA1-1CD7-45B5-9281-E6AE7C287CB7}.Debug_CpuOnly|x64.ActiveCfg = Debug_CpuOnly|x64
|
||||
{82125DA1-1CD7-45B5-9281-E6AE7C287CB7}.Debug_CpuOnly|x64.Build.0 = Debug_CpuOnly|x64
|
||||
{82125DA1-1CD7-45B5-9281-E6AE7C287CB7}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{82125DA1-1CD7-45B5-9281-E6AE7C287CB7}.Debug|x64.Build.0 = Debug|x64
|
||||
{82125DA1-1CD7-45B5-9281-E6AE7C287CB7}.Release_CpuOnly|x64.ActiveCfg = Release_CpuOnly|x64
|
||||
{82125DA1-1CD7-45B5-9281-E6AE7C287CB7}.Release_CpuOnly|x64.Build.0 = Release_CpuOnly|x64
|
||||
{82125DA1-1CD7-45B5-9281-E6AE7C287CB7}.Release|x64.ActiveCfg = Release|x64
|
||||
{82125DA1-1CD7-45B5-9281-E6AE7C287CB7}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -1695,5 +1710,6 @@ Global
|
|||
{BA6A65C5-92A2-4040-ADC3-0727A45694F6} = {977ECCB7-598D-4548-B95B-BACA9CC7D98B}
|
||||
{3BDF52CD-7F3C-42BC-AB78-CF5BBC5F4AB4} = {772A0DB3-4710-4281-8AA9-A9F1F7C543D3}
|
||||
{1141DC61-E014-4DEC-9157-F6B1FC055C7A} = {772A0DB3-4710-4281-8AA9-A9F1F7C543D3}
|
||||
{82125DA1-1CD7-45B5-9281-E6AE7C287CB7} = {6F19321A-65E7-4829-B00C-3886CD6C6EDE}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -176,10 +176,12 @@ public:
|
|||
template<typename ElemType>
|
||||
struct VariableBuffer
|
||||
{
|
||||
size_t m_numberOfSamples = 0;
|
||||
|
||||
//
|
||||
// All elements of a sequence, concatenated.
|
||||
// For dense inputs, the number of samples is given by the the length of
|
||||
// this vector / product of tensor dimensions. E.g. for a tensor of dimension
|
||||
// [2,2] and 12 elements in the buffer, the number of samples is 3.
|
||||
// For sparse inputs, the number of samples is indicated by the m_colIndices field.
|
||||
//
|
||||
std::vector<ElemType> m_buffer;
|
||||
|
||||
|
|
|
@ -238,14 +238,14 @@ VariableLayout CNTKEvalExtended<ElemType>::ToVariableLayout(const ComputationNod
|
|||
auto matrix = dynamic_pointer_cast<Matrix<ElemType>>(n->ValuePtr());
|
||||
return VariableLayout
|
||||
{
|
||||
/* name */ n->GetName(),
|
||||
/* type */ sizeof(ElemType) == sizeof(float) ? VariableLayout::Float32 : VariableLayout::Float64,
|
||||
/* storage */ matrix ? matrix->GetMatrixType() == MatrixType::DENSE ? VariableLayout::Dense :
|
||||
/* name */ n->GetName(),
|
||||
/* type */ sizeof(ElemType) == sizeof(float) ? VariableLayout::Float32 : VariableLayout::Float64,
|
||||
/* storage */ matrix ? matrix->GetMatrixType() == MatrixType::DENSE ? VariableLayout::Dense :
|
||||
matrix->GetMatrixType() == MatrixType::SPARSE ? VariableLayout::Sparse :
|
||||
VariableLayout::Undetermined :
|
||||
VariableLayout::Undetermined,
|
||||
/* dimension */ n->GetSampleLayout().GetNumElements(),
|
||||
/* dynamic axis */ wstring(n->GetMBLayout()->GetAxisName())
|
||||
/* dimension */ n->GetSampleLayout().GetNumElements(),
|
||||
/* dynamic axis */ wstring(n->GetMBLayout() ? n->GetMBLayout()->GetAxisName() : L"*")
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -304,11 +304,39 @@ void CNTKEvalExtended<ElemType>::ForwardPass(const Variables<ElemType>& inputs,
|
|||
for (auto& input : m_inputMatrices)
|
||||
{
|
||||
VariableBuffer<ElemType> buffer = inputs[i];
|
||||
int numRows = input.second.sampleLayout.GetNumElements();
|
||||
int numCols = buffer.m_numberOfSamples;
|
||||
shared_ptr<Matrix<ElemType>> matrix = dynamic_pointer_cast<Matrix<ElemType>>(input.second.matrix);
|
||||
auto type = matrix->GetMatrixType();
|
||||
auto type = matrix->GetMatrixType();
|
||||
int numRows = input.second.sampleLayout.GetNumElements();
|
||||
|
||||
if (type == MatrixType::DENSE)
|
||||
{
|
||||
if (buffer.m_buffer.size() % numRows != 0)
|
||||
{
|
||||
RuntimeError("Input %ls: Expected input data to be a multiple of %ld, but it is %ld", m_inputNodes[i]->GetName().c_str(), numRows, buffer.m_buffer.size());
|
||||
}
|
||||
if (buffer.m_buffer.size() == 0)
|
||||
{
|
||||
RuntimeError("Input %ls: Expected at least one element.", m_inputNodes[i]->GetName().c_str());
|
||||
}
|
||||
}
|
||||
else if (type == MatrixType::SPARSE)
|
||||
{
|
||||
if (buffer.m_colIndices.size() < 2)
|
||||
{
|
||||
RuntimeError("Input %ls: Expected at least one element.", m_inputNodes[i]->GetName().c_str());
|
||||
}
|
||||
if (buffer.m_colIndices[0] != 0)
|
||||
{
|
||||
RuntimeError("Input %ls: First element of column indices must be 0", m_inputNodes[i]->GetName().c_str());
|
||||
}
|
||||
if (buffer.m_colIndices[buffer.m_colIndices.size()-1] != buffer.m_indices.size())
|
||||
{
|
||||
RuntimeError("Input %ls: Last element of column indices must be equal to the size of indices (%ld), but was %d", m_inputNodes[i]->GetName().c_str(), buffer.m_indices.size(), buffer.m_colIndices[buffer.m_colIndices.size() - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
int numCols = type == MatrixType::DENSE ? buffer.m_buffer.size() / numRows : buffer.m_colIndices.size() - 1;
|
||||
assert(numCols >= 1);
|
||||
input.second.pMBLayout->Init(1, numCols);
|
||||
input.second.pMBLayout->AddSequence(0, 0, 0, numCols);
|
||||
|
||||
|
|
|
@ -0,0 +1,269 @@
|
|||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "EvalTestHelper.h"
|
||||
|
||||
using namespace Microsoft::MSR::CNTK;
|
||||
|
||||
namespace Microsoft { namespace MSR { namespace CNTK { namespace Test {
|
||||
|
||||
// Used for retrieving the model appropriate for the element type (float / double)
|
||||
template<typename ElemType>
|
||||
using GetEvalProc = void(*)(IEvaluateModelExtended<ElemType>**);
|
||||
|
||||
typedef std::pair<std::wstring, std::vector<float>*> Variable;
|
||||
typedef std::map<std::wstring, std::vector<float>*> Variables;
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(EvalTestSuite, EvalFixture)
|
||||
|
||||
IEvaluateModelExtended<float>* SetupNetworkAndGetLayouts(std::string modelDefinition, VariableSchema& inputLayouts, VariableSchema& outputLayouts)
|
||||
{
|
||||
// Load the eval library
|
||||
auto hModule = LoadLibrary(L"evaldll.dll");
|
||||
if (hModule == nullptr)
|
||||
{
|
||||
auto err = GetLastError();
|
||||
throw std::exception((boost::format("Cannot load evaldll.dll: 0x%08lx") % err).str().c_str());
|
||||
}
|
||||
|
||||
// Get the factory method to the evaluation engine
|
||||
std::string func = "GetEvalExtendedF";
|
||||
auto procAddress = GetProcAddress(hModule, func.c_str());
|
||||
auto getEvalProc = (GetEvalProc<float>)procAddress;
|
||||
|
||||
// Native model evaluation instance
|
||||
IEvaluateModelExtended<float> *eval;
|
||||
getEvalProc(&eval);
|
||||
|
||||
try
|
||||
{
|
||||
eval->CreateNetwork(modelDefinition);
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
fprintf(stderr, ex.what());
|
||||
throw;
|
||||
}
|
||||
fflush(stderr);
|
||||
|
||||
// Get the model's layers dimensions
|
||||
outputLayouts = eval->GetOutputSchema();
|
||||
|
||||
for (auto vl : outputLayouts)
|
||||
{
|
||||
fprintf(stderr, "Output dimension: %d\n", vl.m_numElements);
|
||||
fprintf(stderr, "Output name: %ls\n", vl.m_name.c_str());
|
||||
}
|
||||
|
||||
eval->StartForwardEvaluation({outputLayouts[0].m_name});
|
||||
inputLayouts = eval->GetInputSchema();
|
||||
|
||||
return eval;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(EvalConstantPlusTest)
|
||||
{
|
||||
// Setup model for adding two constants (1 + 2)
|
||||
std::string modelDefinition =
|
||||
"deviceId = -1 \n"
|
||||
"precision = \"float\" \n"
|
||||
"traceLevel = 1 \n"
|
||||
"run=NDLNetworkBuilder \n"
|
||||
"NDLNetworkBuilder=[ \n"
|
||||
"v1 = Constant(1) \n"
|
||||
"v2 = Constant(2) \n"
|
||||
"ol = Plus(v1, v2, tag=\"output\") \n"
|
||||
"FeatureNodes = (v1) \n"
|
||||
"] \n";
|
||||
|
||||
VariableSchema inputLayouts;
|
||||
VariableSchema outputLayouts;
|
||||
IEvaluateModelExtended<float> *eval;
|
||||
eval = SetupNetworkAndGetLayouts(modelDefinition, inputLayouts, outputLayouts);
|
||||
|
||||
// Allocate the output values layer
|
||||
std::vector<VariableBuffer<float>> outputBuffer(1);
|
||||
|
||||
// Allocate the input values layer (empty)
|
||||
|
||||
std::vector<VariableBuffer<float>> inputBuffer;
|
||||
|
||||
// We can call the evaluate method and get back the results...
|
||||
eval->ForwardPass(inputBuffer, outputBuffer);
|
||||
|
||||
std::vector<float> expected{ 3 /* 1 + 2 */ };
|
||||
auto buf = outputBuffer[0].m_buffer;
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(buf.begin(), buf.end(), expected.begin(), expected.end());
|
||||
|
||||
eval->Destroy();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(EvalScalarTimesTest)
|
||||
{
|
||||
std::string modelDefinition =
|
||||
"deviceId = -1 \n"
|
||||
"precision = \"float\" \n"
|
||||
"traceLevel = 1 \n"
|
||||
"run=NDLNetworkBuilder \n"
|
||||
"NDLNetworkBuilder=[ \n"
|
||||
"i1 = Input(1) \n"
|
||||
"o1 = Times(Constant(3), i1, tag=\"output\") \n"
|
||||
"FeatureNodes = (i1) \n"
|
||||
"] \n";
|
||||
|
||||
VariableSchema inputLayouts;
|
||||
VariableSchema outputLayouts;
|
||||
IEvaluateModelExtended<float> *eval;
|
||||
eval = SetupNetworkAndGetLayouts(modelDefinition, inputLayouts, outputLayouts);
|
||||
|
||||
// Allocate the output values layer
|
||||
std::vector<VariableBuffer<float>> outputBuffer(1);
|
||||
|
||||
// Allocate the input values layer
|
||||
std::vector<VariableBuffer<float>> inputBuffer(1);
|
||||
inputBuffer[0].m_buffer = { 2 };
|
||||
|
||||
// We can call the evaluate method and get back the results...
|
||||
eval->ForwardPass(inputBuffer, outputBuffer);
|
||||
|
||||
std::vector<float> expected{ 6 };
|
||||
auto buf = outputBuffer[0].m_buffer;
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(buf.begin(), buf.end(), expected.begin(), expected.end());
|
||||
|
||||
eval->Destroy();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(EvalScalarTimesDualOutputTest)
|
||||
{
|
||||
std::string modelDefinition =
|
||||
"deviceId = -1 \n"
|
||||
"precision = \"float\" \n"
|
||||
"traceLevel = 1 \n"
|
||||
"run=NDLNetworkBuilder \n"
|
||||
"NDLNetworkBuilder=[ \n"
|
||||
"i1 = Input(1) \n"
|
||||
"i2 = Input(1) \n"
|
||||
"o1 = Times(Constant(3), i1, tag=\"output\") \n"
|
||||
"o2 = Times(Constant(5), i1, tag=\"output\") \n"
|
||||
"FeatureNodes = (i1) \n"
|
||||
"] \n";
|
||||
|
||||
VariableSchema inputLayouts;
|
||||
VariableSchema outputLayouts;
|
||||
IEvaluateModelExtended<float> *eval;
|
||||
eval = SetupNetworkAndGetLayouts(modelDefinition, inputLayouts, outputLayouts);
|
||||
|
||||
// Allocate the output values layer
|
||||
std::vector<VariableBuffer<float>> outputBuffer(1);
|
||||
|
||||
// Allocate the input values layer
|
||||
std::vector<VariableBuffer<float>> inputBuffer(1);
|
||||
inputBuffer[0].m_buffer = { 2 };
|
||||
|
||||
// We can call the evaluate method and get back the results...
|
||||
// TODO: Indicate to ForwardPass that we want output o2 only
|
||||
eval->ForwardPass(inputBuffer, outputBuffer);
|
||||
|
||||
std::vector<float> expected{ 6 };
|
||||
auto buf = outputBuffer[0].m_buffer;
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(buf.begin(), buf.end(), expected.begin(), expected.end());
|
||||
|
||||
eval->Destroy();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(EvalDenseTimesTest)
|
||||
{
|
||||
std::string modelDefinition =
|
||||
"deviceId = -1 \n"
|
||||
"precision = \"float\" \n"
|
||||
"traceLevel = 1 \n"
|
||||
"run=NDLNetworkBuilder \n"
|
||||
"NDLNetworkBuilder=[ \n"
|
||||
"i1 = Input(4) \n"
|
||||
"o1 = Times(Constant(2, rows=1, cols=4), i1, tag=\"output\") \n"
|
||||
"FeatureNodes = (i1) \n"
|
||||
"] \n";
|
||||
|
||||
VariableSchema inputLayouts;
|
||||
VariableSchema outputLayouts;
|
||||
IEvaluateModelExtended<float> *eval;
|
||||
eval = SetupNetworkAndGetLayouts(modelDefinition, inputLayouts, outputLayouts);
|
||||
|
||||
// Allocate the output values layer
|
||||
std::vector<VariableBuffer<float>> outputBuffer(1);
|
||||
|
||||
// Number of inputs must adhere to the schema
|
||||
std::vector<VariableBuffer<float>> inputBuffer1(0);
|
||||
BOOST_REQUIRE_THROW(eval->ForwardPass(inputBuffer1, outputBuffer), std::exception); // Not enough inputs
|
||||
|
||||
// Number of elements in the input must adhere to the schema
|
||||
std::vector<VariableBuffer<float>> inputBuffer(1);
|
||||
inputBuffer[0].m_buffer = { 1, 2, 3 };
|
||||
BOOST_REQUIRE_THROW(eval->ForwardPass(inputBuffer, outputBuffer), std::exception); // Not enough elements in the sample
|
||||
|
||||
// Output values and shape must be correct.
|
||||
inputBuffer[0].m_buffer = { 1, 2, 3, 4 };
|
||||
eval->ForwardPass(inputBuffer, outputBuffer);
|
||||
|
||||
std::vector<float> expected{ 20 };
|
||||
auto buf = outputBuffer[0].m_buffer;
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(buf.begin(), buf.end(), expected.begin(), expected.end());
|
||||
|
||||
eval->Destroy();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(EvalSparseTimesTest)
|
||||
{
|
||||
std::string modelDefinition =
|
||||
"deviceId = -1 \n"
|
||||
"precision = \"float\" \n"
|
||||
"traceLevel = 1 \n"
|
||||
"run=NDLNetworkBuilder \n"
|
||||
"NDLNetworkBuilder=[ \n"
|
||||
"i1 = SparseInput(3) \n"
|
||||
"o1 = Times(Constant(2, rows=1, cols=3), i1, tag=\"output\") \n"
|
||||
"FeatureNodes = (i1) \n"
|
||||
"] \n";
|
||||
|
||||
VariableSchema inputLayouts;
|
||||
VariableSchema outputLayouts;
|
||||
IEvaluateModelExtended<float> *eval;
|
||||
eval = SetupNetworkAndGetLayouts(modelDefinition, inputLayouts, outputLayouts);
|
||||
|
||||
// Allocate the output values layer
|
||||
std::vector<VariableBuffer<float>> outputBuffer(1);
|
||||
|
||||
// Allocate the input values layer
|
||||
std::vector<VariableBuffer<float>> inputBuffer(1);
|
||||
inputBuffer[0].m_buffer = {1, 2, 3, 5, 6};
|
||||
inputBuffer[0].m_indices = {0, 2, 2, 1, 2};
|
||||
|
||||
inputBuffer[0].m_colIndices = {};
|
||||
BOOST_REQUIRE_THROW(eval->ForwardPass(inputBuffer, outputBuffer), std::exception); // Empty input
|
||||
|
||||
inputBuffer[0].m_colIndices = { 0 };
|
||||
BOOST_REQUIRE_THROW(eval->ForwardPass(inputBuffer, outputBuffer), std::exception); // Empty input
|
||||
|
||||
inputBuffer[0].m_colIndices = { 1, 0 };
|
||||
BOOST_REQUIRE_THROW(eval->ForwardPass(inputBuffer, outputBuffer), std::exception); // Illegal: First entry must be 0
|
||||
|
||||
inputBuffer[0].m_colIndices = { 0, 2, 2, 4 };
|
||||
BOOST_REQUIRE_THROW(eval->ForwardPass(inputBuffer, outputBuffer), std::exception); // Illegal: Last entry must be indices.size()
|
||||
|
||||
inputBuffer[0].m_colIndices = { 0, 2, 2, 5 };
|
||||
|
||||
// We can call the evaluate method and get back the results...
|
||||
eval->ForwardPass(inputBuffer, outputBuffer);
|
||||
|
||||
// [2,2,2] * [1,2,3]^T etc.
|
||||
std::vector<float> expected{ 6, 0, 28 };
|
||||
auto buf = outputBuffer[0].m_buffer;
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(buf.begin(), buf.end(), expected.begin(), expected.end());
|
||||
eval->Destroy();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
}}}}
|
|
@ -0,0 +1,115 @@
|
|||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "boost/filesystem.hpp"
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace Microsoft { namespace MSR { namespace CNTK { namespace Test {
|
||||
|
||||
struct EvalFixture
|
||||
{
|
||||
// This fixture sets up paths so the tests can assume the right location for finding the configuration
|
||||
// file as well as the input data and control data.
|
||||
// subPath : an optional sub path (or full path) for the location of data.
|
||||
EvalFixture(string subPath = "", string envVariableErrorMessage = "")
|
||||
{
|
||||
BOOST_TEST_MESSAGE("Setup fixture");
|
||||
m_initialWorkingPath = boost::filesystem::current_path().generic_string();
|
||||
BOOST_TEST_MESSAGE("Current working directory: " + m_initialWorkingPath);
|
||||
fprintf(stderr, "Current working directory: %s\n", m_initialWorkingPath.c_str());
|
||||
|
||||
boost::filesystem::path path(boost::unit_test::framework::master_test_suite().argv[0]);
|
||||
m_parentPath = boost::filesystem::canonical(path.parent_path()).generic_string();
|
||||
fprintf(stderr, "Executable path: %s\n", m_parentPath.c_str());
|
||||
|
||||
m_testDataPath = m_parentPath + "/../../../Tests/UnitTests/EvalTests";
|
||||
boost::filesystem::path absTestPath(m_testDataPath);
|
||||
absTestPath = boost::filesystem::canonical(absTestPath);
|
||||
m_testDataPath = absTestPath.generic_string();
|
||||
|
||||
BOOST_TEST_MESSAGE("Setting test data path to: " + m_testDataPath);
|
||||
fprintf(stderr, "Test path: %s\n", m_testDataPath.c_str());
|
||||
|
||||
string newCurrentPath(m_testDataPath);
|
||||
|
||||
// Determine if a sub-path has been specified and it is not a relative path
|
||||
if (subPath.length())
|
||||
{
|
||||
// Retrieve the full path from the environment variable (if any)
|
||||
// Currently limited to a single expansion of an environment variable at the beginning of the string.
|
||||
if (subPath[0] == '%')
|
||||
{
|
||||
auto end = subPath.find_last_of(subPath[0]);
|
||||
string environmentVariable = subPath.substr(1, end - 1);
|
||||
|
||||
BOOST_TEST_MESSAGE("Retrieving environment variable: " + environmentVariable);
|
||||
fprintf(stderr, "Retrieving environment variable: %s\n", environmentVariable.c_str());
|
||||
|
||||
const char* p = std::getenv(environmentVariable.c_str());
|
||||
if (p)
|
||||
{
|
||||
newCurrentPath = p + subPath.substr(end + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_TEST_MESSAGE("Invalid environment variable: " + subPath);
|
||||
fprintf(stderr, "Invalid environment variable: %s\n", subPath.c_str());
|
||||
|
||||
if (!envVariableErrorMessage.empty())
|
||||
{
|
||||
BOOST_TEST_MESSAGE(envVariableErrorMessage);
|
||||
fprintf(stderr, envVariableErrorMessage.c_str());
|
||||
}
|
||||
|
||||
newCurrentPath = m_testDataPath;
|
||||
}
|
||||
}
|
||||
else if ((subPath[0] == '/' && subPath[1] == '//') || (subPath[0] == '\\' && subPath[1] == '\\'))
|
||||
{
|
||||
newCurrentPath = subPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
newCurrentPath = m_testDataPath + subPath;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST_MESSAGE("Setting current path to: " + newCurrentPath);
|
||||
fprintf(stderr, "Set current path to: %s\n", newCurrentPath.c_str());
|
||||
boost::filesystem::current_path(newCurrentPath);
|
||||
|
||||
BOOST_TEST_MESSAGE("Current working directory is now: " + boost::filesystem::current_path().generic_string());
|
||||
fprintf(stderr, "Current working directory is now: %s\n", boost::filesystem::current_path().generic_string().c_str());
|
||||
}
|
||||
|
||||
~EvalFixture()
|
||||
{
|
||||
BOOST_TEST_MESSAGE("Teardown fixture");
|
||||
BOOST_TEST_MESSAGE("Reverting current path to: " + m_initialWorkingPath);
|
||||
fprintf(stderr, "Set current path to: %s\n", m_initialWorkingPath.c_str());
|
||||
boost::filesystem::current_path(m_initialWorkingPath);
|
||||
}
|
||||
|
||||
string m_initialWorkingPath;
|
||||
string m_testDataPath;
|
||||
string m_parentPath;
|
||||
|
||||
string initialPath()
|
||||
{
|
||||
return m_initialWorkingPath;
|
||||
}
|
||||
string testDataPath()
|
||||
{
|
||||
return m_testDataPath;
|
||||
}
|
||||
string currentPath()
|
||||
{
|
||||
return boost::filesystem::current_path().generic_string();
|
||||
}
|
||||
};
|
||||
}}}}
|
|
@ -0,0 +1,165 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug_CpuOnly|x64">
|
||||
<Configuration>Debug_CpuOnly</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release_CpuOnly|x64">
|
||||
<Configuration>Release_CpuOnly</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{82125DA1-1CD7-45B5-9281-E6AE7C287CB7}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>EvalTests</RootNamespace>
|
||||
<ProjectName>EvalTests</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="$(SolutionDir)\CNTK.Cpp.props" />
|
||||
<PropertyGroup Condition="$(DebugBuild)" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(ReleaseBuild)" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<Choose>
|
||||
<When Condition="Exists('$(BOOST_INCLUDE_PATH)') And Exists('$(BOOST_LIB_PATH)')">
|
||||
<PropertyGroup>
|
||||
<HasBoost>true</HasBoost>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
<Otherwise>
|
||||
<PropertyGroup>
|
||||
<HasBoost>false</HasBoost>
|
||||
</PropertyGroup>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Condition="$(GpuBuild)" Label="ExtensionSettings">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\CUDA $(CudaVersion).props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<LinkIncremental>$(DebugBuild)</LinkIncremental>
|
||||
<OutDir>$(OutDir)\UnitTests\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(BOOST_INCLUDE_PATH);$(SolutionDir)Source\Common\Include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(OutDir)..;$(BOOST_LIB_PATH)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="$(DebugBuild)">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
<OpenMPSupport>true</OpenMPSupport>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<CudaCompile>
|
||||
<TargetMachinePlatform>64</TargetMachinePlatform>
|
||||
<CodeGeneration>compute_20,sm_20;compute_30,sm_30;%(CodeGeneration)</CodeGeneration>
|
||||
</CudaCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="$(ReleaseBuild)">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<OpenMPSupport>false</OpenMPSupport>
|
||||
<AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="$(GpuBuild)">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(CudaInclude)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories);$(CudaLibPath)</AdditionalLibraryDirectories>
|
||||
<DelayLoadDLLs>%(DelayLoadDLLs);nvml.dll;$(CudaRuntimeDll)</DelayLoadDLLs>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="$(CpuOnlyBuild)">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>CPUONLY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="EvalTestHelper.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="EvalExtendedTests.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<Target Name="Build" Condition="$(HasBoost)" Outputs="$(TargetPath)" DependsOnTargets="$(BuildDependsOn)" />
|
||||
<ImportGroup Condition="$(GpuBuild)" Label="ExtensionTargets">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\CUDA $(CudaVersion).targets" />
|
||||
</ImportGroup>
|
||||
<Target Name="CheckDependencies">
|
||||
<Warning Condition="!$(HasBoost)" Text="MathTests requires the Boost library to build. Please see https://github.com/Microsoft/CNTK/wiki/Setup-CNTK-on-Windows#boost for installation instructions." />
|
||||
</Target>
|
||||
<Target Name="CopyUnitTestDependencies" AfterTargets="Build">
|
||||
<PropertyGroup>
|
||||
<CuDnnDll Condition="$(GpuBuild) And Exists('$(OutDir)..\cudnn64_4.dll')">$(OutDir)..\cudnn64_4.dll</CuDnnDll>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<UnitTestDependencies Include="$(OutDir)..\CNTK.Core.BS;$(OutDir)..\evaldll.dll;$(OutDir)..\Math.dll;$(OutDir)..\libacml_mp_dll.dll;$(OutDir)..\libifcoremd.dll;$(OutDir)..\libifportmd.dll;$(OutDir)..\libiomp*.dll;$(OutDir)..\libmmd.dll;$(OutDir)..\svml_dispmd.dll;" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(GpuBuild)">
|
||||
<UnitTestDependencies Include="$(OutDir)..\CNTK.Core.BS;$(OutDir)..\evaldll.dll;$(OutDir)..\cuda*.dll;$(OutDir)..\svml_dispmd.dll;$(CuDnnDll);$(UnitTestDependencies)" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(UnitTestDependencies)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true">
|
||||
<Output TaskParameter="DestinationFiles" ItemName="NewFileWrites" />
|
||||
</Copy>
|
||||
</Target>
|
||||
</Project>
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Common">
|
||||
<UniqueIdentifier>{d40728fd-2b10-4923-87b7-d8fef54fd89f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Data">
|
||||
<UniqueIdentifier>{5eb4cbb2-7932-472c-8fd6-d3edd7c0bd42}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="EvalTestHelper.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="EvalExtendedTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,10 @@
|
|||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// Boost Unit Test Project.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#define BOOST_TEST_MODULE EvalTests
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
|
@ -0,0 +1,24 @@
|
|||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS // "secure" CRT not available on all platforms
|
||||
#define _SCL_SECURE_NO_WARNINGS // current API of matrix does not allow safe invokations. TODO: change api to proper one.
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "targetver.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
||||
#include "Eval.h"
|
||||
|
||||
//Adding required boost header
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/format.hpp>
|
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
// Including SDKDDKVer.h defines the highest available Windows platform.
|
||||
|
||||
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
|
||||
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
|
||||
|
||||
#include <SDKDDKVer.h>
|
Загрузка…
Ссылка в новой задаче