Skip to content

Commit

Permalink
Merge branch 'master' into blis/PythonV2
Browse files Browse the repository at this point in the history
  • Loading branch information
jeanfad committed Sep 6, 2016
2 parents 9229cf0 + a423aa8 commit ea012e8
Show file tree
Hide file tree
Showing 21 changed files with 239 additions and 229 deletions.
89 changes: 46 additions & 43 deletions CNTK.sln

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion Examples/Evaluation/CPPEvalClient-CntkSln/README.md

This file was deleted.

1 change: 0 additions & 1 deletion Examples/Evaluation/CSEvalClient-CntkSln/README.md

This file was deleted.

15 changes: 3 additions & 12 deletions Examples/Evaluation/CSEvalClient/CSEvalClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>$(SolutionDir)..\..\$(Platform)\CSEvalClient.$(Configuration)\</OutputPath>
Expand All @@ -46,8 +45,7 @@
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="EvalWrapper, Version=0.0.0.0, Culture=neutral, processorArchitecture=AMD64">
Expand Down Expand Up @@ -93,12 +91,5 @@
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Research.CNTK.CpuEval-mkl.1.7\build\net45\Microsoft.Research.CNTK.CpuEval-mkl.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Research.CNTK.CpuEval-mkl.1.7\build\net45\Microsoft.Research.CNTK.CpuEval-mkl.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Target>
</Project>
72 changes: 31 additions & 41 deletions Examples/Evaluation/CSEvalClient/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,23 @@ private static void Main(string[] args)
Console.ReadLine();
}

/// <summary>
/// Checks whether the file exists. If not, write the error message on the console and throw FileNotFoundException.
/// </summary>
/// <param name="filePath">The file to check.</param>
/// <param name="errorMsg">The message to write on console if the file does not exist.</param>
private static void ThrowIfFileNotExist(string filePath, string errorMsg)
{
if (!File.Exists(filePath))
{
if (!string.IsNullOrEmpty(errorMsg))
{
Console.WriteLine(errorMsg);
}
throw new FileNotFoundException(string.Format("File '{0}' not found.", filePath));
}
}

/// <summary>
/// Evaluates a trained model and obtains a single layer output
/// </summary>
Expand All @@ -110,11 +127,8 @@ private static void EvaluateModelSingleLayer()
{
// Load model
string modelFilePath = Path.Combine(Environment.CurrentDirectory, @"..\Output\Models\01_OneHidden");
if (!File.Exists(modelFilePath))
{
Console.WriteLine("Error: The model {0} does not exist. Please follow instructions in README.md in <CNTK>/Examples/Image/MNIST to create the model.", modelFilePath);
throw new FileNotFoundException(string.Format("File {0} not found.", modelFilePath));
}
ThrowIfFileNotExist(modelFilePath,
string.Format("Error: The model '{0}' does not exist. Please follow instructions in README.md in <CNTK>/Examples/Image/MNIST to create the model.", modelFilePath));

model.CreateNetwork(string.Format("modelPath=\"{0}\"", modelFilePath), deviceId: -1);

Expand Down Expand Up @@ -165,11 +179,8 @@ private static void EvaluateModelMultipleLayers()

// Load model
string modelFilePath = Path.Combine(Environment.CurrentDirectory, @"..\Output\Models\01_OneHidden");
if (!File.Exists(modelFilePath))
{
Console.WriteLine("Error: The model {0} does not exist. Please follow instructions in README.md in <CNTK>/Examples/Image/MNIST to create the model.", modelFilePath);
throw new FileNotFoundException(string.Format("File {0} not found.", modelFilePath));
}
ThrowIfFileNotExist(modelFilePath,
string.Format("Error: The model '{0}' does not exist. Please follow instructions in README.md in <CNTK>/Examples/Image/MNIST to create the model.", modelFilePath));

var desiredOutputLayers = new List<string>() { hiddenLayerName, outputLayerName };
model.CreateNetwork(string.Format("modelPath=\"{0}\"", modelFilePath), deviceId: -1, outputNodeNames: desiredOutputLayers);
Expand Down Expand Up @@ -223,11 +234,7 @@ private static void EvaluateNetworkSingleLayer()
// This network (AddOperatorConstant_ndl_deprecated.cntk) is a simple network consisting of a single binary operator (Plus)
// operating over a single input and a constant
string networkFilePath = Path.Combine(workingDirectory, @"AddOperatorConstant_ndl_deprecated.cntk");
if (!File.Exists(networkFilePath))
{
Console.WriteLine("Error: The network configuration file {0} does not exist.", networkFilePath);
throw new FileNotFoundException(string.Format("File {0} not found.", networkFilePath));
}
ThrowIfFileNotExist(networkFilePath, string.Format("Error: The network configuration file '{0}' does not exist.", networkFilePath));

string networkDescription = File.ReadAllText(networkFilePath);
model.CreateNetwork(networkDescription, deviceId: -1);
Expand Down Expand Up @@ -273,11 +280,7 @@ private static void EvaluateNetworkSingleLayerNoInput()
// This network (AddOperatorConstantNoInput_ndl_deprecated.cntk) is a simple network consisting of a single binary operator (Plus)
// operating over a two constants, therefore no input is necessary.
string networkFilePath = Path.Combine(workingDirectory, @"AddOperatorConstantNoInput_ndl_deprecated.cntk");
if (!File.Exists(networkFilePath))
{
Console.WriteLine("Error: The network configuration file {0} does not exist.", networkFilePath);
throw new FileNotFoundException(string.Format("File {0} not found.", networkFilePath));
}
ThrowIfFileNotExist(networkFilePath, string.Format("Error: The network configuration file '{0}' does not exist.", networkFilePath));

string networkDescription = File.ReadAllText(networkFilePath);
model.CreateNetwork(networkDescription, deviceId: -1);
Expand Down Expand Up @@ -374,21 +377,15 @@ private static void EvaluateMultipleModels()

// Load model
string modelFilePath = Path.Combine(Environment.CurrentDirectory, @"..\Output\Models\02_Convolution");
if (!File.Exists(modelFilePath))
{
Console.WriteLine("Error: The model {0} does not exist. Please follow instructions in README.md in <CNTK>/Examples/Image/MNIST to create the model.", modelFilePath);
throw new FileNotFoundException(string.Format("File {0} not found.", modelFilePath));
}
ThrowIfFileNotExist(modelFilePath,
string.Format("Error: The model '{0}' does not exist. Please follow instructions in README.md in <CNTK>/Examples/Image/MNIST to create the model.", modelFilePath));

// Initializes the model instances
ModelEvaluator.Initialize(numConcurrentModels, modelFilePath);

string testfile = Path.Combine(Environment.CurrentDirectory, @"Test-28x28_cntk_text.txt");
if (!File.Exists(testfile))
{
Console.WriteLine("Error: The test file {0} does not exist. Please follow instructions in README.md in <CNTK>/Examples/Image/MNIST to download the data.", testfile);
throw new FileNotFoundException(string.Format("File {0} not found.", testfile));
}
ThrowIfFileNotExist(testfile,
string.Format("Error: The test file '{0}' does not exist. Please follow instructions in README.md in <CNTK>/Examples/Image/MNIST to download the data.", testfile));

Stopwatch sw = new Stopwatch();
sw.Start();
Expand Down Expand Up @@ -466,12 +463,9 @@ public static void EvaluateImageClassificationModel()
using (var model = new IEvaluateModelManagedF())
{
string modelFilePath = Path.Combine(workingDirectory, "ResNet_18.model");
if (!File.Exists(modelFilePath))
{
Console.WriteLine("Error: The model {0} does not exist. Please download the model from https://www.cntk.ai/resnet/ResNet_18.model and save it under ..\\..\\Examples\\Image\\Miscellaneous\\ImageNet\\ResNet.", modelFilePath);
throw new FileNotFoundException(string.Format("File {0} not found.", modelFilePath));
}

ThrowIfFileNotExist(modelFilePath,
string.Format("Error: The model '{0}' does not exist. Please download the model from https://www.cntk.ai/resnet/ResNet_18.model and save it under ..\\..\\Examples\\Image\\Miscellaneous\\ImageNet\\ResNet.", modelFilePath));

model.CreateNetwork(string.Format("modelPath=\"{0}\"", modelFilePath), deviceId: -1);

// Prepare input value in the appropriate structure and size
Expand All @@ -483,11 +477,7 @@ public static void EvaluateImageClassificationModel()

// Transform the image
string imageFileName = Path.Combine(workingDirectory, "zebra.jpg");
if (!File.Exists(imageFileName))
{
Console.WriteLine("Error: The test image file {0} does not exist.", imageFileName);
throw new FileNotFoundException(string.Format("File {0} not found.", imageFileName));
}
ThrowIfFileNotExist(imageFileName, string.Format("Error: The test image file '{0}' does not exist.", imageFileName));

Bitmap bmp = new Bitmap(Bitmap.FromFile(imageFileName));

Expand Down
72 changes: 35 additions & 37 deletions Source/Readers/ReaderLib/BlockRandomizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ BlockRandomizer::BlockRandomizer(
m_globalSamplePosition(SIZE_MAX),
m_epochStartPosition(0),
m_sweepTotalNumberOfSamples(0),
m_lastSeenChunkId(CHUNKID_MAX),
m_chunkRandomizer(std::make_shared<ChunkRandomizer>(deserializer, randomizationRangeInSamples, useLegacyRandomization)),
m_multithreadedGetNextSequences(multithreadedGetNextSequence),
m_prefetchedChunk(CHUNKID_MAX)
Expand All @@ -56,7 +55,7 @@ BlockRandomizer::BlockRandomizer(
// Start a new epoch.
void BlockRandomizer::StartEpoch(const EpochConfiguration& config)
{
m_lastSeenChunkId = CHUNKID_MAX;
m_currentWindowRange = ClosedOpenChunkInterval{};

m_config = config;
if (config.m_totalEpochSizeInSamples == requestDataSize)
Expand Down Expand Up @@ -109,7 +108,7 @@ void BlockRandomizer::PrepareNewSweepIfNeeded(size_t samplePosition)

// Resetting sequence randomizer.
m_sequenceRandomizer->Reset(m_sweep);
m_lastSeenChunkId = CHUNKID_MAX;
m_currentWindowRange = {};
}
}

Expand All @@ -119,7 +118,8 @@ Sequences BlockRandomizer::GetNextSequences(size_t sampleCount)
// Get next sequence descriptions.
Sequences result;
std::vector<RandomizedSequenceDescription> sequences;
result.m_endOfEpoch = GetNextSequenceDescriptions(sampleCount, sequences);
ClosedOpenChunkInterval windowRange;
result.m_endOfEpoch = GetNextSequenceDescriptions(sampleCount, sequences, windowRange);
if (sequences.size() == 0)
{
return result;
Expand All @@ -135,7 +135,7 @@ Sequences BlockRandomizer::GetNextSequences(size_t sampleCount)
}

// Retrieve new data chunks if required.
ChunkIdType chunkToPrefetchNext = LoadDataChunks();
LoadDataChunks(windowRange);

if (m_verbosity >= Debug)
fprintf(stderr, "BlockRandomizer::GetNextSequences(): getting %" PRIu64 " out of %" PRIu64 " sequences for %" PRIu64 " requested samples in sweep %" PRIu64 "\n",
Expand Down Expand Up @@ -176,18 +176,16 @@ Sequences BlockRandomizer::GetNextSequences(size_t sampleCount)
process(i);
}

// Explicitly release chunks that are not needed anymore.
m_sequenceRandomizer->ReleaseChunks();

// Now it is safe to start the new chunk prefetch.
ChunkIdType chunkToPrefetchNext = GetChunkToPrefetch(windowRange);
Prefetch(chunkToPrefetchNext);

return result;
}

// Get next sequence descriptions that do not exceed sample count.
// Returns true if epoch end is reached.
bool BlockRandomizer::GetNextSequenceDescriptions(size_t sampleCount, std::vector<RandomizedSequenceDescription>& result)
bool BlockRandomizer::GetNextSequenceDescriptions(size_t sampleCount, std::vector<RandomizedSequenceDescription>& result, ClosedOpenChunkInterval& windowRange)
{
assert(sampleCount != 0);

Expand All @@ -207,7 +205,7 @@ bool BlockRandomizer::GetNextSequenceDescriptions(size_t sampleCount, std::vecto
assert(sampleCount != 0);

// Randomizing sequences
result = m_sequenceRandomizer->GetNextSequenceDescriptions(sampleCount);
result = m_sequenceRandomizer->GetNextSequenceDescriptions(sampleCount, windowRange);
return false;
}

Expand Down Expand Up @@ -246,18 +244,15 @@ void BlockRandomizer::Decimate(const std::vector<RandomizedSequenceDescription>&
}

// Retrieves chunk data based on the window information provided by SequenceRandomizer
// Returns the next chunk id to prefetch.
ChunkIdType BlockRandomizer::LoadDataChunks()
void BlockRandomizer::LoadDataChunks(const ClosedOpenChunkInterval& windowRange)
{
size_t randomizedEnd = 0;
const auto& window = m_sequenceRandomizer->GetChunkWindow(randomizedEnd);
if (window[randomizedEnd - 1].m_chunkId == m_lastSeenChunkId)
if (windowRange == m_currentWindowRange)
{
// nothing to prefetch.
return CHUNKID_MAX;
// Nothing to do.
return;
}

m_lastSeenChunkId = window[randomizedEnd - 1].m_chunkId;
m_currentWindowRange = windowRange;

// in the loop we are building a new map of currently loaded chunks:
// we are iterating thru all chunks in the window and if they are not in m_chunks map -
Expand All @@ -267,12 +262,12 @@ ChunkIdType BlockRandomizer::LoadDataChunks()
size_t numLoadedChunks = m_chunks.size();

std::vector<bool> needed;
needed.resize(randomizedEnd, false);
needed.resize(windowRange.Size(), false);

// Firstly, make sure we unload all not needed chunks:
for (size_t i = 0; i < randomizedEnd; ++i)
for (size_t i = windowRange.m_begin; i < windowRange.m_end; ++i)
{
auto const& chunk = window[i];
auto const& chunk = m_chunkRandomizer->GetRandomizedChunks()[i];
if (m_decimationMode == DecimationMode::chunk && chunk.m_chunkId % m_config.m_numberOfWorkers != m_config.m_workerRank)
{
continue;
Expand All @@ -285,7 +280,7 @@ ChunkIdType BlockRandomizer::LoadDataChunks()
}
else
{
needed[i] = true;
needed[i - windowRange.m_begin] = true;
}
}

Expand All @@ -294,14 +289,14 @@ ChunkIdType BlockRandomizer::LoadDataChunks()
m_chunks.swap(chunks);

// Adding new ones.
for (size_t i = 0; i < randomizedEnd; ++i)
for (size_t i = windowRange.m_begin; i < windowRange.m_end; ++i)
{
if (!needed[i])
if (!needed[i - windowRange.m_begin])
{
continue;
}

auto const& chunk = window[i];
auto const& chunk = m_chunkRandomizer->GetRandomizedChunks()[i];
if (chunk.m_original->m_id == m_prefetchedChunk && m_prefetch.valid())
{
// Taking prefetched chunk.
Expand Down Expand Up @@ -332,26 +327,29 @@ ChunkIdType BlockRandomizer::LoadDataChunks()
if (m_verbosity >= Notification)
fprintf(stderr, "BlockRandomizer::RetrieveDataChunks: %" PRIu64 " chunks paged-in from chunk window [%u..%u]\n",
m_chunks.size(),
window.front().m_chunkId,
window.back().m_chunkId);

return GetChunkToPrefetch(window.begin() + randomizedEnd, window.end());
m_chunkRandomizer->GetRandomizedChunks()[windowRange.m_begin].m_chunkId,
m_chunkRandomizer->GetRandomizedChunks()[windowRange.m_end - 1].m_chunkId);
}

// Identifies chunk id that should be prefetched.
// TODO: DecimationMode::sequence is not supported because it should eventually go away.
template<class Iter>
ChunkIdType BlockRandomizer::GetChunkToPrefetch(const Iter& begin, const Iter& end)
ChunkIdType BlockRandomizer::GetChunkToPrefetch(const ClosedOpenChunkInterval& windowRange)
{
auto current = begin;
ChunkIdType toBePrefetched = CHUNKID_MAX;
while (current != end)
if (m_decimationMode != DecimationMode::chunk)
{
// For non chunked mode, we do not do prefetch currently.
return toBePrefetched;
}

auto current = windowRange.m_end;
while (current < m_chunkRandomizer->GetRandomizedChunks().size())
{
if (m_chunks.find(current->m_original->m_id) == m_chunks.end() &&
m_decimationMode == DecimationMode::chunk &&
current->m_chunkId % m_config.m_numberOfWorkers == m_config.m_workerRank)
const auto& chunk = m_chunkRandomizer->GetRandomizedChunks()[current];
if (chunk.m_chunkId % m_config.m_numberOfWorkers == m_config.m_workerRank &&
m_chunks.find(chunk.m_original->m_id) == m_chunks.end())
{
toBePrefetched = current->m_original->m_id;
toBePrefetched = chunk.m_original->m_id;
break;
}
++current;
Expand Down
Loading

0 comments on commit ea012e8

Please sign in to comment.