merge with master
This commit is contained in:
Коммит
94bd96eaba
|
@ -27,6 +27,11 @@
|
|||
<CudaVersion Condition="Exists('$(CUDA_PATH_V7_5)') And '$(CudaVersion)' == ''">7.5</CudaVersion>
|
||||
<CudaVersion Condition="Exists('$(CUDA_PATH_V7_0)') And '$(CudaVersion)' == ''">7.0</CudaVersion>
|
||||
|
||||
<HasOpenCv>false</HasOpenCv>
|
||||
<HasOpenCv Condition="Exists('$(OPENCV_PATH)') Or Exists('$(OPENCV_PATH_V31)')">true</HasOpenCv>
|
||||
|
||||
<UseZip>false</UseZip>
|
||||
<UseZip Condition="Exists('$(ZLIB_PATH)')">true</UseZip>
|
||||
</PropertyGroup>
|
||||
|
||||
<Choose>
|
||||
|
@ -70,7 +75,33 @@
|
|||
<UnitTestDlls>$(OutDir)mkl_cntk_s.dll;</UnitTestDlls>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
</Choose>
|
||||
</Choose>
|
||||
|
||||
<PropertyGroup Condition="$(UseZip)">
|
||||
<ZipInclude>$(ZLIB_PATH)\include;$(ZLIB_PATH)\lib\libzip\include;</ZipInclude>
|
||||
<ZipDefine>USE_ZIP</ZipDefine>
|
||||
<ZipLibPath>$(ZLIB_PATH)\lib;</ZipLibPath>
|
||||
<ZipLibs>zlib.lib;zip.lib;</ZipLibs>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="Exists('$(OPENCV_PATH)')">
|
||||
<OpenCvPath>$(OPENCV_PATH)</OpenCvPath>
|
||||
<OpenCvVersion>300</OpenCvVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="Exists('$(OPENCV_PATH_V31)')">
|
||||
<OpenCvPath>$(OPENCV_PATH_V31)</OpenCvPath>
|
||||
<OpenCvVersion>310</OpenCvVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="$(HasOpenCv)">
|
||||
<OpenCvInclude>$(OpenCvPath)\include;</OpenCvInclude>
|
||||
<OpenCvWorld Condition="$(ReleaseBuild)">opencv_world$(OpenCvVersion)</OpenCvWorld>
|
||||
<OpenCvWorld Condition="$(DebugBuild)">opencv_world$(OpenCvVersion)d</OpenCvWorld>
|
||||
<OpenCvLib>$(OpenCvWorld).lib</OpenCvLib>
|
||||
<OpenCvLibPath>$(OpenCvPath)\x64\vc12\lib</OpenCvLibPath>
|
||||
<OpenCvBinPath>$(OpenCvPath)\x64\vc12\bin</OpenCvBinPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(CudaVersion)' == '7.5'">
|
||||
<CudaPath>$(CUDA_PATH_V7_5)</CudaPath>
|
||||
|
|
1
CNTK.sln
1
CNTK.sln
|
@ -1133,6 +1133,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{6826
|
|||
ProjectSection(SolutionItems) = preProject
|
||||
Scripts\pytest.ini = Scripts\pytest.ini
|
||||
Scripts\txt2ctf.py = Scripts\txt2ctf.py
|
||||
Scripts\uci2ctf.py = Scripts\uci2ctf.py
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManagedEvalTests", "Tests\UnitTests\ManagedEvalTests\ManagedEvalTests.csproj", "{CC8DDDCB-D53A-4B30-8596-AEF1C493DB31}"
|
||||
|
|
|
@ -56,8 +56,10 @@
|
|||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Drawing" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CntkBitmapExtensions.cs" />
|
||||
<Compile Include="ModelEvaluator.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
|
||||
//
|
||||
// CntkBitmapExtensions.cs -- extension methods for transforming images used in CNTK.
|
||||
//
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.MSR.CNTK.Extensibility.Managed.CSEvalClient
|
||||
{
|
||||
public static class CntkBitmapExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Resizes an image
|
||||
/// </summary>
|
||||
/// <param name="image">The image to resize</param>
|
||||
/// <param name="width">New width in pixels</param>
|
||||
/// <param name="height">New height in pixesl</param>
|
||||
/// <param name="useHighQuality">Resize quality</param>
|
||||
/// <returns>The resized image</returns>
|
||||
public static Bitmap Resize(this Bitmap image, int width, int height, bool useHighQuality)
|
||||
{
|
||||
var newImg = new Bitmap(width, height);
|
||||
|
||||
newImg.SetResolution(image.HorizontalResolution, image.VerticalResolution);
|
||||
|
||||
using (var g = Graphics.FromImage(newImg))
|
||||
{
|
||||
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
|
||||
if (useHighQuality)
|
||||
{
|
||||
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
|
||||
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
|
||||
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
|
||||
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
|
||||
}
|
||||
else
|
||||
{
|
||||
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default;
|
||||
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.Default;
|
||||
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
|
||||
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Default;
|
||||
}
|
||||
|
||||
var attributes = new ImageAttributes();
|
||||
attributes.SetWrapMode(System.Drawing.Drawing2D.WrapMode.TileFlipXY);
|
||||
g.DrawImage(image, new Rectangle(0, 0, width, height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
|
||||
}
|
||||
|
||||
return newImg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts image pixels in CHW
|
||||
/// </summary>
|
||||
/// <param name="image">The bitmap image to extract features from</param>
|
||||
/// <returns>A list of pixels in HWC order</returns>
|
||||
public static List<float> ExtractCHW(this Bitmap image)
|
||||
{
|
||||
var features = new List<float>(image.Width * image.Height * 3);
|
||||
for (int c = 0; c < 3; c++)
|
||||
{
|
||||
for (int h = 0; h < image.Height; h++)
|
||||
{
|
||||
for (int w = 0; w < image.Width; w++)
|
||||
{
|
||||
var pixel = image.GetPixel(w, h);
|
||||
float v = c == 0 ? pixel.B : c == 1 ? pixel.G : pixel.R;
|
||||
features.Add(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts image pixels in CHW using parallelization
|
||||
/// </summary>
|
||||
/// <param name="image">The bitmap image to extract features from</param>
|
||||
/// <returns>A list of pixels in CHW order</returns>
|
||||
public static List<float> ParallelExtractCHW(this Bitmap image)
|
||||
{
|
||||
// We use local variables to avoid contention on the image object through the multiple threads.
|
||||
int channelStride = image.Width * image.Height;
|
||||
int imageWidth = image.Width;
|
||||
int imageHeight = image.Height;
|
||||
|
||||
var features = new byte[imageWidth * imageHeight * 3];
|
||||
var bitmapData = image.LockBits(new Rectangle(0, 0, imageWidth, imageHeight), ImageLockMode.ReadOnly, image.PixelFormat);
|
||||
IntPtr ptr = bitmapData.Scan0;
|
||||
int bytes = Math.Abs(bitmapData.Stride) * bitmapData.Height;
|
||||
byte[] rgbValues = new byte[bytes];
|
||||
|
||||
int stride = bitmapData.Stride;
|
||||
|
||||
// Copy the RGB values into the array.
|
||||
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
|
||||
|
||||
// The mapping depends on the pixel format
|
||||
// The mapPixel lambda will return the right color channel for the desired pixel
|
||||
Func<int, int, int, int> mapPixel = GetPixelMapper(image.PixelFormat, stride);
|
||||
|
||||
Parallel.For(0, imageHeight, (int h) =>
|
||||
{
|
||||
Parallel.For(0, imageWidth, (int w) =>
|
||||
{
|
||||
Parallel.For(0, 3, (int c) =>
|
||||
{
|
||||
features[channelStride * c + imageWidth * h + w] = rgbValues[mapPixel(h, w, c)];
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
image.UnlockBits(bitmapData);
|
||||
|
||||
return features.Select(b => (float)b).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts image pixels in HWC
|
||||
/// </summary>
|
||||
/// <param name="image">The bitmap image to extract features from</param>
|
||||
/// <returns>A list of pixels in HWC order</returns>
|
||||
public static List<float> ExtractHWC(this Bitmap image)
|
||||
{
|
||||
var features = new List<float>(image.Width * image.Height * 3);
|
||||
for (int w = 0; w < image.Width; w++)
|
||||
{
|
||||
for (int h = 0; h < image.Height; h++)
|
||||
{
|
||||
for (int c = 0; c < 3; c++)
|
||||
{
|
||||
var pixel = image.GetPixel(w, h);
|
||||
float v = c == 0 ? pixel.B : c == 1 ? pixel.G : pixel.R;
|
||||
|
||||
features.Add(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts image pixels in HWC using multiple threads
|
||||
/// </summary>
|
||||
/// <param name="image">The bitmap image to extract features from</param>
|
||||
/// <returns>A list of pixels in HWC order</returns>
|
||||
public static List<float> ParallelExtractHWC(this Bitmap image)
|
||||
{
|
||||
int heightStride = image.Width * 3;
|
||||
int widthStride = image.Height * 3;
|
||||
int imageWidth = image.Width;
|
||||
int imageHeight = image.Height;
|
||||
|
||||
var features = new byte[image.Width * image.Height * 3];
|
||||
var bitmapData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, image.PixelFormat);
|
||||
IntPtr ptr = bitmapData.Scan0;
|
||||
int bytes = Math.Abs(bitmapData.Stride) * bitmapData.Height;
|
||||
byte[] rgbValues = new byte[bytes];
|
||||
|
||||
int stride = bitmapData.Stride;
|
||||
|
||||
// Copy the RGB values into the array.
|
||||
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
|
||||
|
||||
// The mapping depends on the pixel format
|
||||
// The mapPixel lambda will return the right color channel for the desired pixel
|
||||
Func<int, int, int, int> mapPixel = GetPixelMapper(image.PixelFormat, stride);
|
||||
|
||||
Parallel.For(0, 3, (int c) =>
|
||||
{
|
||||
Parallel.For(0, imageHeight, (int h) =>
|
||||
{
|
||||
Parallel.For(0, imageWidth, (int w) =>
|
||||
{
|
||||
features[w * widthStride + h * 3 + c] = rgbValues[mapPixel(h, w, c)];
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
image.UnlockBits(bitmapData);
|
||||
|
||||
return features.Select(b => (float)b).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a function for extracting the R-G-B values properly from an image based on its pixel format
|
||||
/// </summary>
|
||||
/// <param name="pixelFormat">The image's pixel format</param>
|
||||
/// <param name="heightStride">The stride (row byte count)</param>
|
||||
/// <returns>A function with signature (height, width, channel) returning the corresponding color value</returns>
|
||||
private static Func<int, int, int, int> GetPixelMapper(PixelFormat pixelFormat, int heightStride)
|
||||
{
|
||||
switch (pixelFormat)
|
||||
{
|
||||
case PixelFormat.Format32bppArgb:
|
||||
return (h, w, c) => h * heightStride + w * 4 + c; // bytes are B-G-R-A
|
||||
case PixelFormat.Format24bppRgb:
|
||||
default:
|
||||
return (h, w, c) => h * heightStride + w * 3 + c; // bytes are B-G-R
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
|
@ -40,9 +41,16 @@ namespace Microsoft.MSR.CNTK.Extensibility.Managed.CSEvalClient
|
|||
///
|
||||
/// EvaluateMultipleModels
|
||||
/// ----------------------
|
||||
/// This case requires the 02_Convolution model and the Test-28x28.txt test file which are part of the <CNTK>/Examples/Image/MNIST example.
|
||||
/// This case requires the 02_Convolution model and the Test-28x28_cntk_text.txt test file which are part of the <CNTK>/Examples/Image/MNIST example.
|
||||
/// Refer to <see cref="https://github.com/Microsoft/CNTK/blob/master/Examples/Image/MNIST/README.md"/> for how to train
|
||||
/// the model used in this example.
|
||||
///
|
||||
/// EvaluateImageClassificationModel
|
||||
/// -----------------------
|
||||
/// This case requires the ResNet_18 trained model which can be downloaded from <see cref="https://www.cntk.ai/resnet/ResNet_18.model"/>.
|
||||
/// This case shows how to evaluate a model that was trained with the ImageReader.
|
||||
/// The input for evaluation needs to be transformed in a similar manner as the ImageReader did during training.
|
||||
///
|
||||
/// </description>
|
||||
class Program
|
||||
{
|
||||
|
@ -55,7 +63,7 @@ namespace Microsoft.MSR.CNTK.Extensibility.Managed.CSEvalClient
|
|||
private static void Main(string[] args)
|
||||
{
|
||||
initialDirectory = Environment.CurrentDirectory;
|
||||
|
||||
|
||||
Console.WriteLine("====== EvaluateModelSingleLayer ========");
|
||||
EvaluateModelSingleLayer();
|
||||
|
||||
|
@ -74,6 +82,9 @@ namespace Microsoft.MSR.CNTK.Extensibility.Managed.CSEvalClient
|
|||
Console.WriteLine("\n====== EvaluateMultipleModels ========");
|
||||
EvaluateMultipleModels();
|
||||
|
||||
Console.WriteLine("\n====== EvaluateModelImageInput ========");
|
||||
EvaluateImageClassificationModel();
|
||||
|
||||
Console.WriteLine("Press <Enter> to terminate.");
|
||||
Console.ReadLine();
|
||||
}
|
||||
|
@ -348,7 +359,7 @@ namespace Microsoft.MSR.CNTK.Extensibility.Managed.CSEvalClient
|
|||
// Initializes the model instances
|
||||
ModelEvaluator.Initialize(numConcurrentModels, modelFilePath);
|
||||
|
||||
string testfile = Path.Combine(Environment.CurrentDirectory, @"Test-28x28.txt");
|
||||
string testfile = Path.Combine(Environment.CurrentDirectory, @"Test-28x28_cntk_text.txt");
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
||||
|
@ -361,16 +372,24 @@ namespace Microsoft.MSR.CNTK.Extensibility.Managed.CSEvalClient
|
|||
{
|
||||
Interlocked.Increment(ref count);
|
||||
|
||||
// The first value in the line is the expected label index for the record's outcome
|
||||
int expected = int.Parse(line.Substring(0, line.IndexOf('\t')));
|
||||
var inputs = line.Substring(line.IndexOf('\t') + 1).Split('\t').Select(float.Parse).ToList();
|
||||
// The file format correspond to the CNTK Text Format Reader format (https://github.com/Microsoft/CNTK/wiki/CNTKTextFormat-Reader)
|
||||
var sets = line.Split('|');
|
||||
var labels = sets[1].Trim().Split(' ').Skip(1);
|
||||
var features = sets[2].Trim().Split(' ').Skip(1);
|
||||
|
||||
// Retrieve the 1-hot vector with the label index
|
||||
var expected = labels.Select(float.Parse).Select((v, index) => new { Value = v, Index = index })
|
||||
.Aggregate((a, b) => (a.Value > b.Value) ? a : b)
|
||||
.Index;
|
||||
|
||||
// Retrieve the features
|
||||
var inputs = features.Select(float.Parse).ToList();
|
||||
|
||||
// We can call the evaluate method and get back the results (single layer)...
|
||||
var outputs = ModelEvaluator.Evaluate(inputs);
|
||||
|
||||
// Retrieve the outcome index (so we can compare it with the expected index)
|
||||
int index = 0;
|
||||
var max = outputs.Select(v => new { Value = v, Index = index++ })
|
||||
var max = outputs.Select((v, index) => new { Value = v, Index = index })
|
||||
.Aggregate((a, b) => (a.Value > b.Value) ? a : b)
|
||||
.Index;
|
||||
|
||||
|
@ -394,10 +413,68 @@ namespace Microsoft.MSR.CNTK.Extensibility.Managed.CSEvalClient
|
|||
sw.Stop();
|
||||
ModelEvaluator.DisposeAll();
|
||||
|
||||
Console.WriteLine("The file {0} was processed using {1} concurrent model(s) with an error rate of: {2:P2} ({3} error(s) out of {4} record(s)), and a throughput of {5:N2} records/sec", @"Test-28x28.txt",
|
||||
Console.WriteLine("The file {0} was processed using {1} concurrent model(s) with an error rate of: {2:P2} ({3} error(s) out of {4} record(s)), and a throughput of {5:N2} records/sec", @"Test-28x28_cntk_text.txt",
|
||||
numConcurrentModels, (float)errorCount / count, errorCount, count, (count + errorCount) * 1000.0 / sw.ElapsedMilliseconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method shows how to evaluate a trained image classification model
|
||||
/// </summary>
|
||||
public static void EvaluateImageClassificationModel()
|
||||
{
|
||||
try
|
||||
{
|
||||
// This example requires the RestNet_18 model.
|
||||
// The model can be downloaded from <see cref="https://www.cntk.ai/resnet/ResNet_18.model"/>
|
||||
// The model is assumed to be located at: <CNTK>\Examples\Image\Miscellaneous\ImageNet\ResNet
|
||||
// along with a sample image file named "zebra.jpg".
|
||||
string workingDirectory = Path.Combine(initialDirectory, @"..\..\Examples\Image\Miscellaneous\ImageNet\ResNet");
|
||||
Environment.CurrentDirectory = initialDirectory;
|
||||
|
||||
List<float> outputs;
|
||||
|
||||
using (var model = new IEvaluateModelManagedF())
|
||||
{
|
||||
string modelFilePath = Path.Combine(workingDirectory, "ResNet_18.model");
|
||||
model.CreateNetwork(string.Format("modelPath=\"{0}\"", modelFilePath), deviceId: -1);
|
||||
|
||||
// Prepare input value in the appropriate structure and size
|
||||
var inDims = model.GetNodeDimensions(NodeGroup.Input);
|
||||
if (inDims.First().Value != 224 * 224 * 3)
|
||||
{
|
||||
throw new CNTKRuntimeException(string.Format("The input dimension for {0} is {1} which is not the expected size of {2}.", inDims.First(), inDims.First().Value, 224 * 224 * 3), string.Empty);
|
||||
}
|
||||
|
||||
// Transform the image
|
||||
string imageFileName = Path.Combine(workingDirectory, "zebra.jpg");
|
||||
Bitmap bmp = new Bitmap(Bitmap.FromFile(imageFileName));
|
||||
|
||||
var resized = bmp.Resize(224, 224, true);
|
||||
var resizedCHW = resized.ParallelExtractCHW();
|
||||
var inputs = new Dictionary<string, List<float>>() { {inDims.First().Key, resizedCHW } };
|
||||
|
||||
// We can call the evaluate method and get back the results (single layer output)...
|
||||
var outDims = model.GetNodeDimensions(NodeGroup.Output);
|
||||
outputs = model.Evaluate(inputs, outDims.First().Key);
|
||||
}
|
||||
|
||||
// Retrieve the outcome index (so we can compare it with the expected index)
|
||||
var max = outputs.Select((value, index) => new { Value = value, Index = index })
|
||||
.Aggregate((a, b) => (a.Value > b.Value) ? a : b)
|
||||
.Index;
|
||||
|
||||
Console.WriteLine("Outcome: {0}", max);
|
||||
}
|
||||
catch (CNTKException ex)
|
||||
{
|
||||
Console.WriteLine("Error: {0}\nNative CallStack: {1}\n Inner Exception: {2}", ex.Message, ex.NativeCallStack, ex.InnerException != null ? ex.InnerException.Message : "No Inner Exception");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error: {0}\nCallStack: {1}\n Inner Exception: {2}", ex.Message, ex.StackTrace, ex.InnerException != null ? ex.InnerException.Message : "No Inner Exception");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dumps the output to the console
|
||||
/// </summary>
|
||||
|
|
|
@ -49,25 +49,21 @@ train = [
|
|||
maxEpochs = 10
|
||||
]
|
||||
|
||||
# Note: this reader crashes if randomization is turned on.
|
||||
reader = [
|
||||
readerType = "UCIFastReader"
|
||||
# To get the data (Train-28x28.txt) please run `python mnist_convert.py`
|
||||
# from the 'AdditionalFiles' folder. See REAMDE.md for details.
|
||||
file = "$DataDir$/Train-28x28.txt"
|
||||
|
||||
features = [
|
||||
dim = 784
|
||||
start = 1
|
||||
readerType = "CNTKTextFormatReader"
|
||||
# See ../README.md for details on getting the data (Train-28x28_cntk_text.txt).
|
||||
file = "$DataDir$/Train-28x28_cntk_text.txt"
|
||||
input = [
|
||||
features = [
|
||||
dim = 784
|
||||
format = "dense"
|
||||
]
|
||||
labels = [
|
||||
dim = 10
|
||||
format = "dense"
|
||||
]
|
||||
]
|
||||
|
||||
labels = [
|
||||
dim = 1
|
||||
start = 0
|
||||
labelDim = 10
|
||||
labelMappingFile = "$DataDir$/labelsmap.txt"
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
#######################################
|
||||
|
@ -83,19 +79,17 @@ test = [
|
|||
]
|
||||
|
||||
reader = [
|
||||
readerType = "UCIFastReader"
|
||||
file = "$DataDir$/Test-28x28.txt"
|
||||
|
||||
features = [
|
||||
dim = 784
|
||||
start = 1
|
||||
]
|
||||
|
||||
labels = [
|
||||
dim = 1
|
||||
start = 0
|
||||
labelDim = 10
|
||||
labelMappingFile = "$DataDir$/labelsmap.txt"
|
||||
readerType = "CNTKTextFormatReader"
|
||||
file = "$DataDir$/Test-28x28_cntk_text.txt"
|
||||
input = [
|
||||
features = [
|
||||
dim = 784
|
||||
format = "dense"
|
||||
]
|
||||
labels = [
|
||||
dim = 10
|
||||
format = "dense"
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|Purpose |This example demonstrates usage of the NDL (Network Description Language) to define networks.
|
||||
|Network |NDLNetworkBuilder, simple feed forward and convolutional networks, cross entropy with softmax.
|
||||
|Training |Stochastic gradient descent both with and without momentum.
|
||||
|Comments |There are two config files, details are provided below.
|
||||
|Comments |There are four config files, details are provided below.
|
||||
|
||||
## Running the example
|
||||
|
||||
|
@ -57,7 +57,7 @@ The output folder will be created inside Image/MNIST/.
|
|||
|
||||
### Config files
|
||||
|
||||
There are three config files and corresponding network description files in the 'Config' folder:
|
||||
There are four config files and the corresponding network description files in the 'Config' folder:
|
||||
|
||||
1. 01_OneHidden.ndl is a simple, one hidden layer network that produces 2.3% of error.
|
||||
To run the sample, navigate to the Data folder and run the following command:
|
||||
|
@ -74,7 +74,11 @@ As a result, it achieves around 0.8% of error after training for just 2 epochs (
|
|||
To run the sample, navigate to the Data folder and run the following command:
|
||||
`cntk configFile=../Config/03_ConvBatchNorm.cntk`
|
||||
|
||||
For more details, refer to .ndl and corresponding .cntk files.
|
||||
4. 04_DeConv.ndl illustrates the usage of Deconvolution and Unpooling. It is a network with one Convolution, one Pooling, one Unpooling and one Deconvolution layer. In fact it is an auto-encoder network where Rectified Linear Unit (ReLU) or Sigmoid layer is now replaced with Convolutional ReLU (for encoding) and Deconvolutional ReLU (for decoding) layers. The network goal is to reconstruct the original signal, with Mean Squared Error (MSE) used to minimize the reconstruction error. Generally such networks are used in semantic segmentation.
|
||||
To run the sample, navigate to the Data folder and run the following command:
|
||||
`cntk configFile=../Config/04_DeConv.cntk`
|
||||
|
||||
For more details, refer to .ndl and the corresponding .cntk files.
|
||||
|
||||
### Additional files
|
||||
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 92 KiB |
|
@ -0,0 +1,183 @@
|
|||
# The configuration file to build language understanding model with ATIS corpus.
|
||||
# LSTM model is built to tage each word in sentences with its semantic label.
|
||||
|
||||
WorkDir = work
|
||||
DataDir = data
|
||||
|
||||
modelPath = $WorkDir$/ATIS.slot.lstm
|
||||
parallelTrain = true
|
||||
|
||||
#stderr = $WorkDir$/log
|
||||
|
||||
command = Train:Test
|
||||
|
||||
precision = "float"
|
||||
deviceId = "auto"
|
||||
|
||||
wordCount = 944 # number of words
|
||||
labelCount = 127 # number of labels
|
||||
Train = [
|
||||
action = train
|
||||
|
||||
traceLevel = 1
|
||||
|
||||
BrainScriptNetworkBuilder = [
|
||||
inputDim = $wordCount$
|
||||
labelDim = $labelCount$
|
||||
featDim = inputDim*3 # contextual words are used as features: previous word, current word, next word.
|
||||
embDim = 150
|
||||
hiddenDim = 300
|
||||
maxLayer = 0
|
||||
initScale = 6
|
||||
initBias = -1.0
|
||||
featuresPW = Input(inputDim) # the previous word
|
||||
featuresCW = Input(inputDim) # the current word
|
||||
featuresNW = Input(inputDim) # the next word
|
||||
features = RowStack(featuresPW : featuresCW : featuresNW)
|
||||
|
||||
labels = Input(labelDim, tag = "label")
|
||||
|
||||
# embedding layer
|
||||
emb = LearnableParameter(embDim, featDim)
|
||||
featEmbedded = Times(emb, features)
|
||||
|
||||
# build the LSTM stack
|
||||
lstmDims[i:0..maxLayer] = hiddenDim
|
||||
NoAuxInputHook (input, lstmState) = BS.Constants.None
|
||||
lstmStack = BS.RNNs.RecurrentLSTMPStack (lstmDims,
|
||||
cellDims=lstmDims,
|
||||
featEmbedded,
|
||||
inputDim=embDim,
|
||||
previousHook=BS.RNNs.PreviousHC,
|
||||
augmentInputHook=BS.RNNs.NoAuxInputHook,
|
||||
augmentInputDim=0,
|
||||
enableSelfStabilization=false)
|
||||
|
||||
lstmOutputLayer = Length (lstmStack)-1
|
||||
LSTMoutput = lstmStack[lstmOutputLayer].h
|
||||
|
||||
W = Parameter(labelDim, hiddenDim, init = "uniform", initValueScale=initScale)
|
||||
b = Parameter(labelDim, 1, init = "fixedValue", value=0)
|
||||
outputs = W * LSTMoutput + b
|
||||
|
||||
cr = CrossEntropyWithSoftmax(labels, outputs)
|
||||
|
||||
criterionNodes = (cr)
|
||||
evaluationNodes = (cr)
|
||||
outputNodes = (outputs)
|
||||
]
|
||||
|
||||
SGD = [
|
||||
# maximum number of epochs
|
||||
maxEpochs = 1 # set to 1 so this can be added to regression test. Increase to 20 get a good accuracy
|
||||
|
||||
# for each epoch, maximum number of input samples(words) is set below
|
||||
epochSize = 36000
|
||||
|
||||
# minibatchSize should be larger than the maximum sentence length
|
||||
minibatchSize = 70
|
||||
|
||||
learningRatesPerSample = 0.01*2:0.005*12:0.001
|
||||
gradUpdateType = "FSAdaGrad"
|
||||
|
||||
gradientClippingWithTruncation = true
|
||||
clippingThresholdPerSample = 15.0
|
||||
|
||||
# number of minibatches to report progress
|
||||
numMBsToShowResult = 100
|
||||
|
||||
firstMBsToShowResult = 10
|
||||
|
||||
# if validation shows that the model has no improvement, then do back-up to the previously
|
||||
# estimated model and reduce learning rate
|
||||
loadBestModel = true
|
||||
|
||||
parallelTrain = [
|
||||
parallelizationMethod = "DataParallelSGD"
|
||||
parallelizationStartEpoch = 2
|
||||
distributedMBReading = true
|
||||
dataParallelSGD = [
|
||||
gradientBits = 1
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
reader = [
|
||||
readerType = "CNTKTextFormatReader"
|
||||
file = "$DataDir$/ATIS.train.cntk.sparse"
|
||||
|
||||
miniBatchMode = "partial"
|
||||
randomize = true
|
||||
input = [
|
||||
featuresPW = [
|
||||
alias = "PW" # previous word
|
||||
dim = $wordCount$
|
||||
format = "sparse"
|
||||
]
|
||||
featuresCW = [
|
||||
alias = "CW" # current word
|
||||
dim = $wordCount$
|
||||
format = "sparse"
|
||||
]
|
||||
featuresNW = [
|
||||
alias = "NW" # next word
|
||||
dim = $wordCount$
|
||||
format = "sparse"
|
||||
]
|
||||
|
||||
labels = [
|
||||
alias = "L" # label
|
||||
dim = $labelCount$
|
||||
format = "sparse"
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
# Test the model built from Train
|
||||
Test = [
|
||||
action = write
|
||||
|
||||
traceLevel = 1
|
||||
epochSize = 0
|
||||
|
||||
defaultHiddenActivity = 0.1
|
||||
BrainScriptNetworkBuilder = [
|
||||
modelAsTrained = BS.Network.Load ("$modelPath$")
|
||||
final = Softmax(modelAsTrained.outputs)
|
||||
]
|
||||
|
||||
outputPath = $WorkDir$/model.writeaction
|
||||
outputNodeNames = final
|
||||
|
||||
reader = [
|
||||
readerType = "CNTKTextFormatReader"
|
||||
file = "$DataDir$/ATIS.test.cntk.sparse"
|
||||
|
||||
miniBatchMode = "partial"
|
||||
randomize = false
|
||||
input = [
|
||||
featuresPW = [
|
||||
alias = "PW" # previous word
|
||||
dim = $wordCount$
|
||||
format = "sparse"
|
||||
]
|
||||
featuresCW = [
|
||||
alias = "CW" # current word
|
||||
dim = $wordCount$
|
||||
format = "sparse"
|
||||
]
|
||||
featuresNW = [
|
||||
alias = "NW" # next word
|
||||
dim = $wordCount$
|
||||
format = "sparse"
|
||||
]
|
||||
|
||||
labels = [
|
||||
alias = "L" # label
|
||||
dim = $labelCount$
|
||||
format = "sparse"
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
|
@ -0,0 +1,163 @@
|
|||
# Build Language Understanding Models with CNTK
|
||||
|
||||
This example demonstrates how to use build language understanding model with CNTK using ATIS data set. This example is similar to
|
||||
[SLU example](https://github.com/Microsoft/CNTK/tree/master/Examples/Text/Miscellaneous/SLU). They are different in that
|
||||
- CNTKTextFormatReader is used here, instead of LUSequenceReader
|
||||
- With CNTKTextFormatReader, the input format is much more flexible. In the example setting, sparse contextual feature vectors are explored
|
||||
- Sparse label input is used.
|
||||
|
||||
The Air travel information system (ATIS) corpus is used for training and testing.
|
||||
## Download the example
|
||||
The data and configuration is checked in to github. You can get it by command:
|
||||
|
||||
`git clone https://github.com/Microsoft/cntk`
|
||||
|
||||
The example is under folder:
|
||||
`<cntk_root>\Examples\Text\ATIS`
|
||||
|
||||
## Data File Format
|
||||
There are four files under `data` sub-folder
|
||||
|
||||
|Files |Content |
|
||||
|:----------------------|:--------|
|
||||
|ATIS.train.cntk.sparse |featurized training data set
|
||||
|ATIS.test.cntk.sparse |featurized test data set
|
||||
|ATIS.vocab |all words extracted from training data. Vocab size: 944
|
||||
|ATIS.labels |all semantic labels extracted from training data. Total labels: 127
|
||||
|
||||
We preprocess ATIS data by converting words into word indexes, and labels into label IDs in order to use
|
||||
[CNTKTextFormatReader](https://github.com/Microsoft/CNTK/wiki/CNTKTextFormat-Reader). You can use any
|
||||
script/tool to preprocess your text data files. In this example, data is already preprocessed.
|
||||
|
||||
The last two files ATIS.vocab and ATIS.labels are not really required to run the example. They are included for evaluation and debugging purpose.
|
||||
E.g. they can be used to convert .sparse files back to original text files.
|
||||
|
||||
To understand the data format (two .sparse files), let's start with a sample sentence:
|
||||
```
|
||||
BOS i would like to find a flight from charlotte to Las Vegas that makes a stop in St. Louis EOS
|
||||
```
|
||||
it is converted into the following text:
|
||||
```
|
||||
1 |PW 1:1 |CW 1:1 |NW 12:1 |L 126:1
|
||||
1 |PW 1:1 |CW 12:1 |NW 39:1 |L 126:1
|
||||
1 |PW 12:1 |CW 39:1 |NW 28:1 |L 126:1
|
||||
1 |PW 39:1 |CW 28:1 |NW 3:1 |L 126:1
|
||||
1 |PW 28:1 |CW 3:1 |NW 86:1 |L 126:1
|
||||
1 |PW 3:1 |CW 86:1 |NW 15:1 |L 126:1
|
||||
1 |PW 86:1 |CW 15:1 |NW 10:1 |L 126:1
|
||||
1 |PW 15:1 |CW 10:1 |NW 4:1 |L 126:1
|
||||
1 |PW 10:1 |CW 4:1 |NW 101:1 |L 126:1
|
||||
1 |PW 4:1 |CW 101:1 |NW 3:1 |L 48:1
|
||||
1 |PW 101:1 |CW 3:1 |NW 92:1 |L 126:1
|
||||
1 |PW 3:1 |CW 92:1 |NW 90:1 |L 78:1
|
||||
1 |PW 92:1 |CW 90:1 |NW 33:1 |L 123:1
|
||||
1 |PW 90:1 |CW 33:1 |NW 338:1 |L 126:1
|
||||
1 |PW 33:1 |CW 338:1 |NW 15:1 |L 126:1
|
||||
1 |PW 338:1 |CW 15:1 |NW 132:1 |L 126:1
|
||||
1 |PW 15:1 |CW 132:1 |NW 17:1 |L 126:1
|
||||
1 |PW 132:1 |CW 17:1 |NW 72:1 |L 126:1
|
||||
1 |PW 17:1 |CW 72:1 |NW 144:1 |L 71:1
|
||||
1 |PW 72:1 |CW 144:1 |NW 2:1 |L 119:1
|
||||
1 |PW 144:1 |CW 2:1 |NW 2:1 |L 126:1
|
||||
```
|
||||
where the first column identifies the sequence (sentence) ID, which is the same for all words of the same sentence. There are four input streams: PW, CW, NW, L.
|
||||
The input "PW" represents the previous word ID, "CW" for current word, and "NW" for next word. Input name "L" is for labels. The input names can be anything you
|
||||
like and you can add more input as needed, e.g. words in a bigger window.
|
||||
|
||||
Words "BOS" and "EOS" denote beginning of sentence and end of sentences respectively.
|
||||
|
||||
Each line above represents one sample (word). E.g. the meaning of this line: `1 |PW 4:1 |CW 101:1 |NW 3:1 |L 48:1`:
|
||||
* the sequence ID is 1
|
||||
* the current word is "charlotte" whose word ID is 101
|
||||
* the previous word is "from" whose ID is 4
|
||||
* the next word is "to" whose ID is 3
|
||||
* the semantic label is "B-fromloc.city_name" whose label Id is 48.
|
||||
|
||||
All word IDs, label IDs and corresponding words and labels are stored in ATIS.vocab and ATIS.labels.
|
||||
|
||||
## CNTK Configuration
|
||||
|
||||
In this example, we use BrainScript to create one-layer LSTM with embedding for slot tagging. The consolidated config file is ATIS.cntk. One can check the file (with some comments)
|
||||
for details, especially how the reader is configured in ATIS.cntk.
|
||||
|
||||
reader=[
|
||||
readerType = "CNTKTextFormatReader"
|
||||
file = "$DataDir$/ATIS.train.cntk.sparse"
|
||||
|
||||
miniBatchMode = "partial"
|
||||
randomize = true
|
||||
input = [
|
||||
featuresPW = [
|
||||
alias = "PW" # previous word
|
||||
dim = $wordCount$
|
||||
format = "sparse"
|
||||
]
|
||||
featuresCW = [
|
||||
alias = "CW" # current word
|
||||
dim = $wordCount$
|
||||
format = "sparse"
|
||||
]
|
||||
featuresNW = [
|
||||
alias = "NW" # next word
|
||||
dim = $wordCount$
|
||||
format = "sparse"
|
||||
]
|
||||
|
||||
labels = [
|
||||
alias = "L" # label
|
||||
dim = $labelCount$
|
||||
format = "sparse"
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
The above section tell CNTK to use CNTKTextFormatReader to read data from the file "$DataDir/ATIS.train.cntk.sparse". The same input names (PW, CW, NW, L) are used to refer inputs (features and labels) provided in data files. The input is read into different
|
||||
feature vectors: featuresPW, featuresCW, featuresNW and labels. These vectors are later used to build LSTM node with BrainScript as follows.
|
||||
```
|
||||
featuresPW = Input(inputDim)
|
||||
featuresCW = Input(inputDim)
|
||||
featuresNW = Input(inputDim)
|
||||
features = RowStack(featuresPW : featuresCW : featuresNW)
|
||||
labels=Input(labelDim, tag="label")
|
||||
# embedding layer
|
||||
emb = LearnableParameter(embDim, featDim)
|
||||
featEmbedded = Times(emb, features)
|
||||
# build the LSTM stack
|
||||
lstmDims[i:0..maxLayer] = hiddenDim
|
||||
NoAuxInputHook (input, lstmState) = BS.Constants.None
|
||||
lstmStack = BS.RNNs.RecurrentLSTMPStack (lstmDims,
|
||||
cellDims=lstmDims,
|
||||
featEmbedded,
|
||||
inputDim=embDim,
|
||||
previousHook=BS.RNNs.PreviousHC,
|
||||
augmentInputHook=BS.RNNs.NoAuxInputHook,
|
||||
augmentInputDim=0,
|
||||
enableSelfStabilization=false)
|
||||
lstmOutputLayer = Length (lstmStack)-1
|
||||
LSTMoutput = lstmStack[lstmOutputLayer].h
|
||||
|
||||
```
|
||||
A few other notes about the config:
|
||||
- it is important to specify the format is "sparse".
|
||||
- the gradUpdateType is set FSAdaGrad. This setting reports better model accuracy comparing any other update methods.
|
||||
- multiple LSTM layers can be used by changing the value of maxLayer.
|
||||
|
||||
## Run the example
|
||||
|
||||
One can run the example locally or on Philly (for Microsoft internal users).
|
||||
|
||||
To run locally,
|
||||
|
||||
```sh
|
||||
> mkdir work # the default work_dir
|
||||
> cntk.exe configFile=ATIS.cntk
|
||||
```
|
||||
|
||||
By default, the maxEpochs is set to 1 to save training time. One can change it to larger value such as 20 in order to get a good model accuracy. Depends on GPU, it normally takes about 20 minutes to run 20 epochs on single GPU, and slot F1 score is about 93.
|
||||
|
||||
**For Microsoft users only**, to run the job on Philly:
|
||||
- first upload data folder to philly cloud. e.g. `\\storage.gcr.philly.selfhost.corp.microsoft.com\pnrsy\<your_alias>\ATIS `
|
||||
- update the config file to philly cloud, e.g. `\\storage.gcr.philly.selfhost.corp.microsoft.com\pnrsy_scratch\<your_alias>\ATIS`
|
||||
- go to http://philly/ to create a new job by specifying data folder and config file, and start the job.
|
||||
|
||||
More details about Philly, including how to upload data to Philly and start jobs, can be found [here](https://microsoft.sharepoint.com/teams/ATISG/SitePages/Philly%20Users%20Guide.aspx)
|
|
@ -0,0 +1,127 @@
|
|||
B-aircraft_code
|
||||
B-airline_code
|
||||
B-airline_name
|
||||
B-airport_code
|
||||
B-airport_name
|
||||
B-arrive_date.date_relative
|
||||
B-arrive_date.day_name
|
||||
B-arrive_date.day_number
|
||||
B-arrive_date.month_name
|
||||
B-arrive_date.today_relative
|
||||
B-arrive_time.end_time
|
||||
B-arrive_time.period_mod
|
||||
B-arrive_time.period_of_day
|
||||
B-arrive_time.start_time
|
||||
B-arrive_time.time
|
||||
B-arrive_time.time_relative
|
||||
B-booking_class
|
||||
B-city_name
|
||||
B-class_type
|
||||
B-compartment
|
||||
B-connect
|
||||
B-cost_relative
|
||||
B-day_name
|
||||
B-day_number
|
||||
B-days_code
|
||||
B-depart_date.date_relative
|
||||
B-depart_date.day_name
|
||||
B-depart_date.day_number
|
||||
B-depart_date.month_name
|
||||
B-depart_date.today_relative
|
||||
B-depart_date.year
|
||||
B-depart_time.end_time
|
||||
B-depart_time.period_mod
|
||||
B-depart_time.period_of_day
|
||||
B-depart_time.start_time
|
||||
B-depart_time.time
|
||||
B-depart_time.time_relative
|
||||
B-economy
|
||||
B-fare_amount
|
||||
B-fare_basis_code
|
||||
B-flight
|
||||
B-flight_days
|
||||
B-flight_mod
|
||||
B-flight_number
|
||||
B-flight_stop
|
||||
B-flight_time
|
||||
B-fromloc.airport_code
|
||||
B-fromloc.airport_name
|
||||
B-fromloc.city_name
|
||||
B-fromloc.state_code
|
||||
B-fromloc.state_name
|
||||
B-meal
|
||||
B-meal_code
|
||||
B-meal_description
|
||||
B-mod
|
||||
B-month_name
|
||||
B-or
|
||||
B-period_of_day
|
||||
B-restriction_code
|
||||
B-return_date.date_relative
|
||||
B-return_date.day_name
|
||||
B-return_date.day_number
|
||||
B-return_date.month_name
|
||||
B-return_date.today_relative
|
||||
B-return_time.period_mod
|
||||
B-return_time.period_of_day
|
||||
B-round_trip
|
||||
B-state_code
|
||||
B-state_name
|
||||
B-stoploc.airport_code
|
||||
B-stoploc.airport_name
|
||||
B-stoploc.city_name
|
||||
B-stoploc.state_code
|
||||
B-time
|
||||
B-time_relative
|
||||
B-today_relative
|
||||
B-toloc.airport_code
|
||||
B-toloc.airport_name
|
||||
B-toloc.city_name
|
||||
B-toloc.country_name
|
||||
B-toloc.state_code
|
||||
B-toloc.state_name
|
||||
B-transport_type
|
||||
I-airline_name
|
||||
I-airport_name
|
||||
I-arrive_date.day_number
|
||||
I-arrive_time.end_time
|
||||
I-arrive_time.period_of_day
|
||||
I-arrive_time.start_time
|
||||
I-arrive_time.time
|
||||
I-arrive_time.time_relative
|
||||
I-city_name
|
||||
I-class_type
|
||||
I-cost_relative
|
||||
I-depart_date.day_number
|
||||
I-depart_date.today_relative
|
||||
I-depart_time.end_time
|
||||
I-depart_time.period_of_day
|
||||
I-depart_time.start_time
|
||||
I-depart_time.time
|
||||
I-depart_time.time_relative
|
||||
I-economy
|
||||
I-fare_amount
|
||||
I-fare_basis_code
|
||||
I-flight_mod
|
||||
I-flight_number
|
||||
I-flight_stop
|
||||
I-flight_time
|
||||
I-fromloc.airport_name
|
||||
I-fromloc.city_name
|
||||
I-fromloc.state_name
|
||||
I-meal_code
|
||||
I-meal_description
|
||||
I-restriction_code
|
||||
I-return_date.date_relative
|
||||
I-return_date.day_number
|
||||
I-return_date.today_relative
|
||||
I-round_trip
|
||||
I-state_name
|
||||
I-stoploc.city_name
|
||||
I-time
|
||||
I-today_relative
|
||||
I-toloc.airport_name
|
||||
I-toloc.city_name
|
||||
I-toloc.state_name
|
||||
I-transport_type
|
||||
O
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,944 @@
|
|||
</s>
|
||||
BOS
|
||||
EOS
|
||||
to
|
||||
from
|
||||
flights
|
||||
the
|
||||
on
|
||||
what
|
||||
me
|
||||
flight
|
||||
show
|
||||
i
|
||||
boston
|
||||
san
|
||||
a
|
||||
denver
|
||||
in
|
||||
and
|
||||
francisco
|
||||
atlanta
|
||||
is
|
||||
pittsburgh
|
||||
dallas
|
||||
all
|
||||
baltimore
|
||||
list
|
||||
philadelphia
|
||||
like
|
||||
are
|
||||
airlines
|
||||
of
|
||||
between
|
||||
that
|
||||
washington
|
||||
pm
|
||||
leaving
|
||||
please
|
||||
morning
|
||||
would
|
||||
fly
|
||||
for
|
||||
city
|
||||
fare
|
||||
wednesday
|
||||
first
|
||||
need
|
||||
after
|
||||
trip
|
||||
oakland
|
||||
there
|
||||
ground
|
||||
round
|
||||
does
|
||||
transportation
|
||||
'd
|
||||
which
|
||||
cheapest
|
||||
you
|
||||
arriving
|
||||
class
|
||||
before
|
||||
available
|
||||
american
|
||||
new
|
||||
fares
|
||||
milwaukee
|
||||
with
|
||||
give
|
||||
have
|
||||
afternoon
|
||||
york
|
||||
st.
|
||||
one
|
||||
dc
|
||||
at
|
||||
way
|
||||
monday
|
||||
leave
|
||||
arrive
|
||||
airport
|
||||
thursday
|
||||
how
|
||||
want
|
||||
tuesday
|
||||
nonstop
|
||||
find
|
||||
am
|
||||
earliest
|
||||
go
|
||||
vegas
|
||||
miami
|
||||
las
|
||||
united
|
||||
information
|
||||
orlando
|
||||
phoenix
|
||||
chicago
|
||||
sunday
|
||||
saturday
|
||||
evening
|
||||
charlotte
|
||||
twenty
|
||||
newark
|
||||
can
|
||||
delta
|
||||
toronto
|
||||
seattle
|
||||
diego
|
||||
kansas
|
||||
indianapolis
|
||||
houston
|
||||
airline
|
||||
noon
|
||||
any
|
||||
friday
|
||||
lake
|
||||
salt
|
||||
's
|
||||
next
|
||||
us
|
||||
o'clock
|
||||
cleveland
|
||||
continental
|
||||
air
|
||||
angeles
|
||||
los
|
||||
august
|
||||
worth
|
||||
do
|
||||
fort
|
||||
july
|
||||
stop
|
||||
code
|
||||
5
|
||||
seventh
|
||||
early
|
||||
memphis
|
||||
tell
|
||||
aircraft
|
||||
downtown
|
||||
or
|
||||
june
|
||||
6
|
||||
louis
|
||||
montreal
|
||||
cincinnati
|
||||
around
|
||||
tomorrow
|
||||
cost
|
||||
going
|
||||
latest
|
||||
petersburg
|
||||
tampa
|
||||
many
|
||||
minneapolis
|
||||
nashville
|
||||
8
|
||||
get
|
||||
mean
|
||||
jose
|
||||
detroit
|
||||
10
|
||||
an
|
||||
departing
|
||||
stopover
|
||||
tacoma
|
||||
by
|
||||
about
|
||||
twa
|
||||
much
|
||||
7
|
||||
leaves
|
||||
may
|
||||
long
|
||||
type
|
||||
burbank
|
||||
see
|
||||
expensive
|
||||
ticket
|
||||
international
|
||||
12
|
||||
travel
|
||||
could
|
||||
dollars
|
||||
than
|
||||
daily
|
||||
columbus
|
||||
service
|
||||
beach
|
||||
'm
|
||||
california
|
||||
9
|
||||
night
|
||||
least
|
||||
know
|
||||
economy
|
||||
time
|
||||
4
|
||||
depart
|
||||
into
|
||||
meal
|
||||
paul
|
||||
coach
|
||||
book
|
||||
april
|
||||
airports
|
||||
northwest
|
||||
la
|
||||
lowest
|
||||
now
|
||||
december
|
||||
less
|
||||
westchester
|
||||
day
|
||||
serves
|
||||
it
|
||||
serve
|
||||
november
|
||||
okay
|
||||
arrives
|
||||
used
|
||||
field
|
||||
love
|
||||
last
|
||||
ontario
|
||||
second
|
||||
county
|
||||
return
|
||||
kind
|
||||
september
|
||||
mitchell
|
||||
general
|
||||
as
|
||||
stops
|
||||
flying
|
||||
2
|
||||
third
|
||||
be
|
||||
direct
|
||||
fifth
|
||||
eighth
|
||||
stopping
|
||||
times
|
||||
breakfast
|
||||
out
|
||||
make
|
||||
capacity
|
||||
car
|
||||
take
|
||||
schedule
|
||||
seating
|
||||
sixth
|
||||
1000
|
||||
number
|
||||
goes
|
||||
cities
|
||||
dinner
|
||||
connecting
|
||||
3
|
||||
dl
|
||||
fourth
|
||||
airfare
|
||||
possible
|
||||
this
|
||||
has
|
||||
served
|
||||
meals
|
||||
ninth
|
||||
looking
|
||||
also
|
||||
restriction
|
||||
week
|
||||
late
|
||||
eastern
|
||||
returning
|
||||
back
|
||||
today
|
||||
interested
|
||||
price
|
||||
business
|
||||
most
|
||||
prices
|
||||
1991
|
||||
two
|
||||
types
|
||||
flies
|
||||
twentieth
|
||||
will
|
||||
through
|
||||
limousine
|
||||
ua
|
||||
bwi
|
||||
via
|
||||
tenth
|
||||
using
|
||||
stand
|
||||
plane
|
||||
ap
|
||||
fifteenth
|
||||
guardia
|
||||
same
|
||||
1
|
||||
should
|
||||
other
|
||||
arrangements
|
||||
f
|
||||
only
|
||||
rental
|
||||
then
|
||||
display
|
||||
your
|
||||
shortest
|
||||
wednesdays
|
||||
listing
|
||||
canadian
|
||||
classes
|
||||
again
|
||||
numbers
|
||||
thirtieth
|
||||
florida
|
||||
express
|
||||
midwest
|
||||
tickets
|
||||
where
|
||||
twelfth
|
||||
sixteenth
|
||||
h
|
||||
north
|
||||
eleventh
|
||||
carolina
|
||||
seventeenth
|
||||
under
|
||||
smallest
|
||||
mco
|
||||
distance
|
||||
lunch
|
||||
either
|
||||
makes
|
||||
if
|
||||
qx
|
||||
transport
|
||||
far
|
||||
hp
|
||||
57
|
||||
october
|
||||
no
|
||||
my
|
||||
m80
|
||||
thank
|
||||
arizona
|
||||
jfk
|
||||
colorado
|
||||
jersey
|
||||
q
|
||||
weekday
|
||||
airplane
|
||||
y
|
||||
planes
|
||||
some
|
||||
departure
|
||||
use
|
||||
ewr
|
||||
their
|
||||
ohio
|
||||
thirty
|
||||
nineteenth
|
||||
when
|
||||
fourteenth
|
||||
explain
|
||||
layover
|
||||
alaska
|
||||
march
|
||||
stopovers
|
||||
live
|
||||
people
|
||||
traveling
|
||||
serving
|
||||
rent
|
||||
hi
|
||||
offer
|
||||
later
|
||||
yes
|
||||
january
|
||||
area
|
||||
logan
|
||||
right
|
||||
booking
|
||||
sfo
|
||||
midnight
|
||||
yn
|
||||
but
|
||||
during
|
||||
landings
|
||||
february
|
||||
dfw
|
||||
abbreviation
|
||||
630
|
||||
both
|
||||
're
|
||||
230
|
||||
qw
|
||||
boeing
|
||||
coming
|
||||
passengers
|
||||
arrange
|
||||
hours
|
||||
qo
|
||||
codes
|
||||
trying
|
||||
tower
|
||||
466
|
||||
canada
|
||||
each
|
||||
530
|
||||
over
|
||||
uses
|
||||
arrivals
|
||||
11
|
||||
southwest
|
||||
281
|
||||
trips
|
||||
838
|
||||
days
|
||||
those
|
||||
takeoffs
|
||||
lufthansa
|
||||
west
|
||||
1100
|
||||
arrival
|
||||
757
|
||||
minnesota
|
||||
anywhere
|
||||
america
|
||||
430
|
||||
thrift
|
||||
let
|
||||
mornings
|
||||
nationair
|
||||
'll
|
||||
kinds
|
||||
cheap
|
||||
close
|
||||
seats
|
||||
pennsylvania
|
||||
name
|
||||
quebec
|
||||
indiana
|
||||
michigan
|
||||
saturdays
|
||||
different
|
||||
taxi
|
||||
provided
|
||||
rates
|
||||
utah
|
||||
these
|
||||
starting
|
||||
sometime
|
||||
costs
|
||||
making
|
||||
bh
|
||||
eighteenth
|
||||
following
|
||||
another
|
||||
ff
|
||||
near
|
||||
747
|
||||
ea
|
||||
1992
|
||||
connect
|
||||
help
|
||||
choices
|
||||
sa
|
||||
maximum
|
||||
wish
|
||||
1115
|
||||
six
|
||||
weekdays
|
||||
more
|
||||
total
|
||||
s
|
||||
dc10
|
||||
d9s
|
||||
2100
|
||||
snack
|
||||
1245
|
||||
georgia
|
||||
72s
|
||||
73s
|
||||
f28
|
||||
heading
|
||||
departures
|
||||
amount
|
||||
825
|
||||
737
|
||||
813
|
||||
ap57
|
||||
sixteen
|
||||
m
|
||||
sorry
|
||||
serviced
|
||||
three
|
||||
miles
|
||||
departs
|
||||
1700
|
||||
requesting
|
||||
718
|
||||
land
|
||||
nevada
|
||||
100
|
||||
so
|
||||
tennessee
|
||||
tuesdays
|
||||
hello
|
||||
destination
|
||||
reservation
|
||||
texas
|
||||
rentals
|
||||
co
|
||||
meaning
|
||||
ap80
|
||||
1500
|
||||
270
|
||||
thursdays
|
||||
philly
|
||||
thirteenth
|
||||
services
|
||||
sundays
|
||||
turboprop
|
||||
stands
|
||||
415
|
||||
provide
|
||||
cars
|
||||
we
|
||||
great
|
||||
mondays
|
||||
include
|
||||
sure
|
||||
't
|
||||
well
|
||||
2134
|
||||
fn
|
||||
555
|
||||
ord
|
||||
934
|
||||
connection
|
||||
296
|
||||
abbreviations
|
||||
755
|
||||
highest
|
||||
hold
|
||||
720
|
||||
fit
|
||||
80
|
||||
soon
|
||||
four
|
||||
ten
|
||||
noontime
|
||||
too
|
||||
offers
|
||||
options
|
||||
within
|
||||
difference
|
||||
c
|
||||
restrictions
|
||||
plan
|
||||
originating
|
||||
describe
|
||||
nw
|
||||
1110
|
||||
connections
|
||||
dulles
|
||||
21
|
||||
733
|
||||
say
|
||||
approximately
|
||||
define
|
||||
852
|
||||
1291
|
||||
rate
|
||||
who
|
||||
proper
|
||||
beginning
|
||||
being
|
||||
329
|
||||
352
|
||||
don
|
||||
1024
|
||||
such
|
||||
wanted
|
||||
615
|
||||
mealtime
|
||||
provides
|
||||
prefer
|
||||
1288
|
||||
257
|
||||
across
|
||||
continent
|
||||
overnight
|
||||
local
|
||||
route
|
||||
746
|
||||
off
|
||||
j31
|
||||
closest
|
||||
19
|
||||
lax
|
||||
l10
|
||||
be1
|
||||
1994
|
||||
red
|
||||
eye
|
||||
not
|
||||
aa
|
||||
dca
|
||||
determine
|
||||
1200
|
||||
1205
|
||||
dtw
|
||||
airfares
|
||||
capacities
|
||||
200
|
||||
town
|
||||
lga
|
||||
300
|
||||
1993
|
||||
database
|
||||
1765
|
||||
eight
|
||||
up
|
||||
originate
|
||||
look
|
||||
cp
|
||||
carries
|
||||
here
|
||||
201
|
||||
located
|
||||
dinnertime
|
||||
1039
|
||||
lastest
|
||||
1222
|
||||
they
|
||||
just
|
||||
d
|
||||
limo
|
||||
3724
|
||||
210
|
||||
stapleton
|
||||
343
|
||||
1145
|
||||
schedules
|
||||
932
|
||||
nonstops
|
||||
without
|
||||
landing
|
||||
b
|
||||
midway
|
||||
217
|
||||
bound
|
||||
727
|
||||
takeoff
|
||||
324
|
||||
train
|
||||
along
|
||||
friends
|
||||
transcontinental
|
||||
missouri
|
||||
reservations
|
||||
lives
|
||||
767
|
||||
269
|
||||
ac
|
||||
atl
|
||||
month
|
||||
taking
|
||||
repeat
|
||||
845
|
||||
airplanes
|
||||
buy
|
||||
still
|
||||
itinerary
|
||||
actually
|
||||
earlier
|
||||
various
|
||||
reaching
|
||||
very
|
||||
names
|
||||
505
|
||||
grounds
|
||||
ap68
|
||||
must
|
||||
kennedy
|
||||
operation
|
||||
4400
|
||||
1201
|
||||
297
|
||||
question
|
||||
combination
|
||||
basis
|
||||
laying
|
||||
1133
|
||||
650
|
||||
tonight
|
||||
43
|
||||
ls
|
||||
sam
|
||||
ap58
|
||||
once
|
||||
nighttime
|
||||
yx
|
||||
kw
|
||||
212
|
||||
1600
|
||||
tpa
|
||||
prior
|
||||
good
|
||||
1800
|
||||
819
|
||||
inform
|
||||
k
|
||||
dc9
|
||||
305
|
||||
anything
|
||||
771
|
||||
459
|
||||
calling
|
||||
designate
|
||||
417
|
||||
spend
|
||||
hou
|
||||
1220
|
||||
directly
|
||||
jet
|
||||
reverse
|
||||
staying
|
||||
l1011
|
||||
belong
|
||||
445
|
||||
515
|
||||
travels
|
||||
order
|
||||
mci
|
||||
150
|
||||
110
|
||||
connects
|
||||
charges
|
||||
minimum
|
||||
intercontinental
|
||||
497766
|
||||
sounds
|
||||
811
|
||||
seat
|
||||
final
|
||||
phl
|
||||
20
|
||||
start
|
||||
823
|
||||
1059
|
||||
271
|
||||
382
|
||||
able
|
||||
put
|
||||
locate
|
||||
hartfield
|
||||
scheduled
|
||||
run
|
||||
225
|
||||
1158
|
||||
equipment
|
||||
begins
|
||||
lands
|
||||
reaches
|
||||
carried
|
||||
wn
|
||||
bn
|
||||
try
|
||||
included
|
||||
130
|
||||
continuing
|
||||
india
|
||||
lester
|
||||
pearson
|
||||
listings
|
||||
1209
|
||||
everywhere
|
||||
sd
|
||||
whether
|
||||
offered
|
||||
486
|
||||
1300
|
||||
950
|
||||
usa
|
||||
1045
|
||||
al
|
||||
currently
|
||||
enroute
|
||||
visit
|
||||
them
|
||||
takes
|
||||
55
|
||||
thing
|
||||
705
|
||||
fridays
|
||||
catch
|
||||
straight
|
||||
advertises
|
||||
having
|
||||
planning
|
||||
listed
|
||||
1055
|
||||
405
|
||||
468
|
||||
equal
|
||||
working
|
||||
sb
|
||||
hopefully
|
||||
dh8
|
||||
symbols
|
||||
sort
|
||||
cover
|
||||
810
|
||||
operating
|
||||
320
|
||||
639
|
||||
seventeen
|
||||
1207
|
||||
608
|
||||
besides
|
||||
companies
|
||||
've
|
||||
got
|
||||
somebody
|
||||
else
|
||||
wants
|
||||
level
|
||||
vicinity
|
||||
1940
|
||||
311
|
||||
mia
|
||||
instead
|
||||
priced
|
||||
eleven
|
||||
comes
|
||||
greatest
|
||||
summer
|
||||
economic
|
||||
bay
|
||||
402
|
||||
gets
|
||||
date
|
||||
1020
|
||||
730
|
||||
400
|
||||
doesn
|
||||
toward
|
||||
home
|
||||
1850
|
||||
1505
|
||||
runs
|
||||
673
|
||||
723
|
||||
thanks
|
||||
bring
|
||||
zone
|
||||
yyz
|
||||
afternoons
|
||||
non
|
||||
largest
|
||||
500
|
||||
come
|
||||
428
|
||||
98
|
||||
qualify
|
||||
279
|
||||
137338
|
||||
d10
|
||||
539
|
||||
fine
|
||||
while
|
||||
665
|
||||
concerning
|
||||
iah
|
||||
1230
|
||||
oak
|
||||
preferably
|
||||
twelve
|
||||
3357
|
||||
323
|
||||
nights
|
||||
229
|
||||
regarding
|
||||
seven
|
||||
inexpensive
|
||||
420
|
||||
416
|
||||
repeating
|
||||
scenario
|
||||
139
|
||||
82
|
||||
kindly
|
||||
limousines
|
||||
345
|
||||
afterwards
|
||||
734
|
||||
place
|
||||
includes
|
||||
106
|
||||
1026
|
||||
124
|
||||
fifteen
|
||||
bna
|
||||
supper
|
||||
oh
|
||||
71
|
||||
thereafter
|
||||
2153
|
||||
year
|
||||
discount
|
||||
1130
|
||||
1030
|
||||
world
|
||||
trans
|
||||
including
|
||||
represented
|
||||
o
|
||||
'hare
|
||||
exceeding
|
||||
815
|
||||
928
|
||||
163
|
||||
bur
|
||||
419
|
||||
cvg
|
||||
1017
|
||||
315
|
||||
842
|
||||
1083
|
||||
0900
|
||||
longest
|
||||
called
|
||||
snacks
|
||||
645
|
||||
ever
|
||||
single
|
24
Makefile
24
Makefile
|
@ -110,7 +110,7 @@ ifdef CUDA_PATH
|
|||
# This is a suggested/default location for NVML
|
||||
INCLUDEPATH+=$(GDK_PATH)/include/nvidia/gdk
|
||||
INCLUDEPATH+=$(CUB_PATH)
|
||||
NVMLPATH=$(GDK_PATH)/src/gdk/nvml/lib
|
||||
NVMLLIBPATH=$(GDK_PATH)/src/gdk/nvml/lib
|
||||
|
||||
# Set up CUDA includes and libraries
|
||||
INCLUDEPATH += $(CUDA_PATH)/include
|
||||
|
@ -232,6 +232,7 @@ ORIGINDIR:='$$ORIGIN'
|
|||
|
||||
CNTKMATH:=cntkmath
|
||||
|
||||
RPATH=-Wl,-rpath,
|
||||
|
||||
########################################
|
||||
# Build info
|
||||
|
@ -246,7 +247,6 @@ ifneq ("$(BUILDINFO_OUTPUT)","Success")
|
|||
$(error Could not generate $(BUILDINFO))
|
||||
endif
|
||||
|
||||
|
||||
########################################
|
||||
# Math library
|
||||
########################################
|
||||
|
@ -324,13 +324,11 @@ CNTKMATH_LIB:= $(LIBDIR)/lib$(CNTKMATH).so
|
|||
ALL += $(CNTKMATH_LIB)
|
||||
SRC+=$(MATH_SRC)
|
||||
|
||||
RPATH=-Wl,-rpath,
|
||||
|
||||
$(CNTKMATH_LIB): $(MATH_OBJ)
|
||||
@echo $(SEPARATOR)
|
||||
@echo creating $@ for $(ARCH) with build type $(BUILDTYPE)
|
||||
@mkdir -p $(dir $@)
|
||||
$(CXX) $(LDFLAGS) -shared $(patsubst %,-L%, $(LIBPATH) $(NVMLPATH)) $(patsubst %,$(RPATH)%, $(ORIGINDIR) $(LIBPATH)) -o $@ $^ $(LIBS) -fopenmp
|
||||
$(CXX) $(LDFLAGS) -shared $(patsubst %,-L%, $(LIBPATH) $(NVMLLIBPATH)) $(patsubst %,$(RPATH)%, $(ORIGINDIR) $(LIBPATH)) -o $@ $^ $(LIBS) -fopenmp
|
||||
|
||||
########################################
|
||||
# CNTKLibrary
|
||||
|
@ -391,13 +389,11 @@ CNTKLIBRARY_LIB:=$(LIBDIR)/lib$(CNTKLIBRARY).so
|
|||
ALL+=$(CNTKLIBRARY_LIB)
|
||||
SRC+=$(CNTKLIBRARY_SRC)
|
||||
|
||||
RPATH=-Wl,-rpath,
|
||||
|
||||
$(CNTKLIBRARY_LIB): $(CNTKLIBRARY_OBJ) | $(CNTKMATH_LIB)
|
||||
@echo $(SEPARATOR)
|
||||
@mkdir -p $(dir $@)
|
||||
@echo building output for $(ARCH) with build type $(BUILDTYPE)
|
||||
$(CXX) $(LDFLAGS) -shared $(patsubst %,-L%, $(LIBDIR) $(LIBPATH) $(NVMLPATH)) $(patsubst %,$(RPATH)%, $(ORIGINDIR) $(LIBPATH)) -o $@ $^ $(LIBS) -l$(CNTKMATH)
|
||||
$(CXX) $(LDFLAGS) -shared $(patsubst %,-L%, $(LIBDIR) $(LIBPATH) $(NVMLLIBPATH)) $(patsubst %,$(RPATH)%, $(ORIGINDIR) $(LIBPATH)) -o $@ $^ $(LIBS) -l$(CNTKMATH)
|
||||
|
||||
########################################
|
||||
# CNTKLibrary tests
|
||||
|
@ -416,13 +412,11 @@ CNTKLIBRARY_TESTS_OBJ := $(patsubst %.cu, $(OBJDIR)/%.o, $(patsubst %.cpp, $(OBJ
|
|||
ALL+=$(CNTKLIBRARY_TESTS)
|
||||
SRC+=$(CNTKLIBRARY_TESTS_SRC)
|
||||
|
||||
RPATH=-Wl,-rpath,
|
||||
|
||||
$(CNTKLIBRARY_TESTS): $(CNTKLIBRARY_TESTS_OBJ) | $(CNTKLIBRARY_LIB)
|
||||
@echo $(SEPARATOR)
|
||||
@mkdir -p $(dir $@)
|
||||
@echo building output for $(ARCH) with build type $(BUILDTYPE)
|
||||
$(CXX) $(LDFLAGS) $(patsubst %,-L%, $(LIBDIR) $(LIBPATH) $(NVMLPATH)) $(patsubst %,$(RPATH)%, $(ORIGINLIBDIR) $(LIBPATH)) -o $@ $^ $(LIBS) -l$(CNTKLIBRARY) -l$(CNTKMATH)
|
||||
$(CXX) $(LDFLAGS) $(patsubst %,-L%, $(LIBDIR) $(LIBPATH) $(NVMLLIBPATH)) $(patsubst %,$(RPATH)%, $(ORIGINLIBDIR) $(LIBPATH)) -o $@ $^ $(LIBS) -l$(CNTKLIBRARY) -l$(CNTKMATH)
|
||||
|
||||
########################################
|
||||
# LibEval
|
||||
|
@ -456,13 +450,11 @@ EVAL_LIB:=$(LIBDIR)/lib$(EVAL).so
|
|||
ALL+=$(EVAL_LIB)
|
||||
SRC+=$(EVAL_SRC)
|
||||
|
||||
RPATH=-Wl,-rpath,
|
||||
|
||||
$(EVAL_LIB): $(EVAL_OBJ)
|
||||
@echo $(SEPARATOR)
|
||||
@mkdir -p $(dir $@)
|
||||
@echo Building $(EVAL_LIB) for $(ARCH) with build type $(BUILDTYPE)
|
||||
$(CXX) $(LDFLAGS) -shared $(patsubst %,-L%, $(LIBDIR) $(LIBPATH)) $(patsubst %,$(RPATH)%, $(ORIGINDIR) $(LIBPATH)) -o $@ $^ $(LIBS)
|
||||
$(CXX) $(LDFLAGS) -shared $(patsubst %,-L%, $(LIBDIR) $(LIBPATH) $(NVMLLIBPATH)) $(patsubst %,$(RPATH)%, $(ORIGINDIR) $(LIBPATH)) -o $@ $^ $(LIBS)
|
||||
|
||||
########################################
|
||||
# Eval Sample client
|
||||
|
@ -477,8 +469,6 @@ EVAL_SAMPLE_CLIENT_OBJ:=$(patsubst %.cpp, $(OBJDIR)/%.o, $(EVAL_SAMPLE_CLIENT_SR
|
|||
ALL+=$(EVAL_SAMPLE_CLIENT)
|
||||
SRC+=$(EVAL_SAMPLE_CLIENT_SRC)
|
||||
|
||||
RPATH=-Wl,-rpath,
|
||||
|
||||
$(EVAL_SAMPLE_CLIENT): $(EVAL_SAMPLE_CLIENT_OBJ) | $(EVAL_LIB) $(CNTKMATH_LIB)
|
||||
@echo $(SEPARATOR)
|
||||
@mkdir -p $(dir $@)
|
||||
|
@ -797,7 +787,7 @@ $(CNTK): $(CNTK_OBJ) | $(CNTKMATH_LIB)
|
|||
@echo $(SEPARATOR)
|
||||
@mkdir -p $(dir $@)
|
||||
@echo building output for $(ARCH) with build type $(BUILDTYPE)
|
||||
$(CXX) $(LDFLAGS) $(patsubst %,-L%, $(LIBDIR) $(LIBPATH) $(NVMLPATH)) $(patsubst %,$(RPATH)%, $(ORIGINLIBDIR) $(LIBPATH)) -o $@ $^ $(LIBS) -l$(CNTKMATH) -fopenmp
|
||||
$(CXX) $(LDFLAGS) $(patsubst %,-L%, $(LIBDIR) $(LIBPATH) $(NVMLLIBPATH)) $(patsubst %,$(RPATH)%, $(ORIGINLIBDIR) $(LIBPATH)) -o $@ $^ $(LIBS) -l$(CNTKMATH) -fopenmp
|
||||
|
||||
# deployable resources: standard library of BS
|
||||
CNTK_CORE_BS:=$(BINDIR)/cntk.core.bs
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
# CNTK
|
||||
|
||||
## Latest news
|
||||
*2016-07-05.* CNTK now supports *Deconvolution* and *Unpooling*. See the usage example in the Network number 4 in [MNIST Sample](https://github.com/Microsoft/CNTK/blob/master/Examples/Image/MNIST/README.md).
|
||||
|
||||
*2016-06-23.* New License Terms for CNTK 1bit-SGD and related components.
|
||||
Effective immediately the License Terms for CNTK 1bit-SGD and related components have changed. The new Terms provide more flexibility and enable new usage scenarios, especially in commercial environments. Read the new Terms at the [standard location](https://cntk1bitsgd.codeplex.com/license). Please note, that while the new Terms are significantly more flexible comparing to the previous ones, they are still **more restrictive** than the main CNTK License. Consequently everything described in [Enabling 1bit-SGD](https://github.com/Microsoft/CNTK/wiki/Enabling-1bit-SGD) section of the Wiki remains valid.
|
||||
|
||||
|
@ -12,8 +14,6 @@ NuGet Package is added to CNTK v.1.5 binaries. See [CNTK Releases page](https://
|
|||
*2016-06-15.* CNTK now supports building against a custom Intel® Math Kernel Library (MKL).
|
||||
See [setup instructions](https://github.com/Microsoft/CNTK/wiki/Setup-CNTK-on-your-machine) on how to set this up for your platform.
|
||||
|
||||
*2016-06-10.* See CNTK v.1.5 binary release announcement in the official [Microsoft Research Blog](https://blogs.msdn.microsoft.com/msr_er/2016/06/10/microsoft-improves-programming-flexibility-of-its-ai-toolkit/)
|
||||
|
||||
See [all news](https://github.com/Microsoft/CNTK/wiki/News).
|
||||
|
||||
## What is CNTK
|
||||
|
|
|
@ -117,6 +117,23 @@ size_t GetMaxEpochs(const ConfigParameters& configParams)
|
|||
return maxEpochs;
|
||||
}
|
||||
|
||||
#ifndef CPUONLY
|
||||
// abort execution is GPU is not supported (e.g. compute capability not supported)
|
||||
void CheckSupportForGpu(DEVICEID_TYPE deviceId)
|
||||
{
|
||||
auto gpuData = GetGpuData(deviceId);
|
||||
if (gpuData.validity == GpuValidity::ComputeCapabilityNotSupported)
|
||||
{
|
||||
InvalidArgument("CNTK: The GPU (%s) has compute capability %d.%d. CNTK is only supported on GPUs with compute capability 3.0 or greater",
|
||||
gpuData.name.c_str(), gpuData.versionMajor, gpuData.versionMinor);
|
||||
}
|
||||
else if (gpuData.validity == GpuValidity::UnknownDevice)
|
||||
{
|
||||
InvalidArgument("CNTK: Unknown GPU with Device ID %d.", gpuData.deviceId);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// special temporary function to guard against a now invalid usage of "truncated" which exists in some IPG production setups
|
||||
static void DisableLegacyTruncationSettings(const ConfigParameters& TopLevelConfig, const ConfigParameters& commandConfig)
|
||||
{
|
||||
|
@ -370,6 +387,30 @@ void PrintUsageInfo()
|
|||
LOGPRINTF(stderr, "-------------------------------------------------------------------\n");
|
||||
}
|
||||
|
||||
// print gpu info for current gpu devices (e.g. Device[0]: cores = 2496; computeCapability = 5.2; type = "Quadro M4000"; memory = 8192 MB)
|
||||
void PrintGpuInfo()
|
||||
{
|
||||
#ifndef CPUONLY
|
||||
std::vector<GpuData> gpusData = GetAllGpusData();
|
||||
|
||||
if (gpusData.empty())
|
||||
{
|
||||
LOGPRINTF(stderr, "No GPUs found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
LOGPRINTF(stderr, "-------------------------------------------------------------------\n");
|
||||
LOGPRINTF(stderr, "GPU info:\n\n");
|
||||
|
||||
for (GpuData& data : gpusData)
|
||||
{
|
||||
LOGPRINTF(stderr, "\t\tDevice[%d]: cores = %d; computeCapability = %d.%d; type = \"%s\"; memory = %lu MB\n",
|
||||
data.deviceId, data.cudaCores, data.versionMajor, data.versionMinor, data.name.c_str(), data.totalMemory);
|
||||
}
|
||||
LOGPRINTF(stderr, "-------------------------------------------------------------------\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// main() for use with BrainScript
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -461,6 +502,21 @@ int wmainWithBS(int argc, wchar_t* argv[]) // called from wmain which is a wrapp
|
|||
let valp = BS::Evaluate(expr); // evaluate parse into a dictionary
|
||||
let& config = valp.AsRef<ScriptableObjects::IConfigRecord>(); // this is the dictionary
|
||||
|
||||
#ifndef CPUONLY
|
||||
auto valpp = config.Find(L"deviceId");
|
||||
if (valpp)
|
||||
{
|
||||
auto valp = *valpp;
|
||||
if (!valp.Is<ScriptableObjects::String>()) // if it's not string 'auto' or 'cpu', then it's a gpu
|
||||
{
|
||||
if (static_cast<int>(valp) >= 0) // gpu (id >= 0)
|
||||
{
|
||||
CheckSupportForGpu(valp); // throws if gpu is not supported
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// legacy parameters that have changed spelling
|
||||
if (config.Find(L"DoneFile")) // variables follow camel case (start with lower-case letters)
|
||||
InvalidArgument("Legacy spelling of 'DoneFile' no longer allowed. Use 'doneFile'.");
|
||||
|
@ -499,6 +555,9 @@ int wmainWithBS(int argc, wchar_t* argv[]) // called from wmain which is a wrapp
|
|||
// echo config info to log
|
||||
PrintBuiltInfo();
|
||||
|
||||
// echo gpu info to log
|
||||
PrintGpuInfo();
|
||||
|
||||
// execute the actions
|
||||
// std::string type = config(L"precision", "float");
|
||||
int numCPUThreads = config(L"numCPUThreads", 0);
|
||||
|
@ -556,6 +615,18 @@ int wmainOldCNTKConfig(int argc, wchar_t* argv[])
|
|||
{
|
||||
ConfigParameters config;
|
||||
std::string rawConfigString = ConfigParameters::ParseCommandLine(argc, argv, config); // get the command param set they want
|
||||
|
||||
#ifndef CPUONLY
|
||||
ConfigValue val = config("deviceId", "auto");
|
||||
if (!EqualCI(val, "cpu") && !EqualCI(val, "auto"))
|
||||
{
|
||||
if (static_cast<int>(val) >= 0) // gpu (id >= 0)
|
||||
{
|
||||
CheckSupportForGpu(static_cast<int>(val)); // throws if gpu is not supported
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool timestamping = config(L"timestamping", false);
|
||||
if (timestamping)
|
||||
{
|
||||
|
@ -599,6 +670,8 @@ int wmainOldCNTKConfig(int argc, wchar_t* argv[])
|
|||
}
|
||||
|
||||
PrintBuiltInfo(); // this one goes to log file
|
||||
PrintGpuInfo();
|
||||
|
||||
std::string timestamp = TimeDateStamp();
|
||||
|
||||
// dump config info
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -53,6 +53,10 @@ namespace Microsoft { namespace MSR { namespace CNTK {
|
|||
|
||||
#ifndef _MSC_VER
|
||||
#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
|
||||
static inline wchar_t* _wcsdup(const wchar_t *s)
|
||||
{
|
||||
return ::wcsdup(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace CNTK
|
||||
|
@ -132,102 +136,76 @@ namespace CNTK
|
|||
class CompositeFunction;
|
||||
class Function;
|
||||
|
||||
namespace _Internal
|
||||
namespace Internal
|
||||
{
|
||||
// A reference counter to be used as the base class for all reference counted types.
|
||||
class _ReferenceCounter
|
||||
// A reference count to be used as the base class for all reference counted types.
|
||||
class CNTK_API ReferenceCount
|
||||
{
|
||||
public:
|
||||
|
||||
// Constructor.
|
||||
_ReferenceCounter() : m_rc(0) {}
|
||||
ReferenceCount();
|
||||
virtual ~ReferenceCount();
|
||||
|
||||
// Destructor.
|
||||
virtual ~_ReferenceCounter() {}
|
||||
|
||||
// Add a reference.
|
||||
// Thread-safe.
|
||||
size_t AddReference()
|
||||
{
|
||||
return ++m_rc;
|
||||
}
|
||||
|
||||
// Remove a reference.
|
||||
// Thread-safe.
|
||||
size_t RemoveReference()
|
||||
{
|
||||
assert(m_rc.load() > 0);
|
||||
return --m_rc;
|
||||
}
|
||||
|
||||
// Return the reference count value
|
||||
size_t GetReferenceCount()
|
||||
{
|
||||
return m_rc.load();
|
||||
}
|
||||
size_t AddReference();
|
||||
size_t RemoveReference();
|
||||
size_t GetReferenceCount();
|
||||
|
||||
private:
|
||||
std::atomic<size_t> m_rc;
|
||||
std::atomic<size_t>* m_rc;
|
||||
};
|
||||
|
||||
// A smart pointer to a reference counted object
|
||||
// T must be a type derived from _Reference_counter
|
||||
// T must be a type derived from ReferenceCount
|
||||
template <class T>
|
||||
class _ReferenceCounterSharedPtr final
|
||||
class CNTK_API ReferenceCountedPtr final
|
||||
{
|
||||
typedef void(*_ReferenceCounterDeleter)(_ReferenceCounter* obj);
|
||||
typedef void(*ReferenceCountedObjectDeleter)(ReferenceCount* obj);
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
_ReferenceCounterSharedPtr(T* ptr = nullptr, _ReferenceCounterDeleter deleter = nullptr) : m_objPtr(ptr), m_deleter(deleter)
|
||||
ReferenceCountedPtr(T* ptr = nullptr, ReferenceCountedObjectDeleter deleter = nullptr) : m_objPtr(ptr), m_deleter(deleter)
|
||||
{
|
||||
Init();
|
||||
AddReferenceIfNeeded();
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
_ReferenceCounterSharedPtr(const _ReferenceCounterSharedPtr& other) : m_objPtr(nullptr), m_deleter(nullptr)
|
||||
ReferenceCountedPtr(const ReferenceCountedPtr& other) : m_objPtr(nullptr), m_deleter(nullptr)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
// Move constructor
|
||||
_ReferenceCounterSharedPtr(_ReferenceCounterSharedPtr&& other) : m_objPtr(nullptr), m_deleter(nullptr)
|
||||
ReferenceCountedPtr(ReferenceCountedPtr&& other) : m_objPtr(nullptr), m_deleter(nullptr)
|
||||
{
|
||||
*this = std::move(other);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
~_ReferenceCounterSharedPtr()
|
||||
~ReferenceCountedPtr()
|
||||
{
|
||||
UnInitialize(m_objPtr, m_deleter);
|
||||
DeleteReferenceIfNeeded(m_objPtr, m_deleter);
|
||||
}
|
||||
|
||||
// Assignment operator
|
||||
_ReferenceCounterSharedPtr& operator=(const _ReferenceCounterSharedPtr& other)
|
||||
ReferenceCountedPtr& operator=(const ReferenceCountedPtr& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
T* oldPtr = m_objPtr;
|
||||
_ReferenceCounterDeleter oldDeleter = m_deleter;
|
||||
ReferenceCountedObjectDeleter oldDeleter = m_deleter;
|
||||
|
||||
m_objPtr = other.m_objPtr;
|
||||
m_deleter = other.m_deleter;
|
||||
Init();
|
||||
AddReferenceIfNeeded();
|
||||
|
||||
UnInitialize(oldPtr, oldDeleter);
|
||||
DeleteReferenceIfNeeded(oldPtr, oldDeleter);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Move-assignment operator
|
||||
_ReferenceCounterSharedPtr& operator=(_ReferenceCounterSharedPtr&& other)
|
||||
ReferenceCountedPtr& operator=(ReferenceCountedPtr&& other)
|
||||
{
|
||||
assert(this != &other);
|
||||
|
||||
T* oldPtr = m_objPtr;
|
||||
_ReferenceCounterDeleter oldDeleter = m_deleter;
|
||||
ReferenceCountedObjectDeleter oldDeleter = m_deleter;
|
||||
|
||||
m_objPtr = other.m_objPtr;
|
||||
m_deleter = other.m_deleter;
|
||||
|
@ -236,16 +214,16 @@ namespace CNTK
|
|||
other.m_objPtr = nullptr;
|
||||
other.m_deleter = nullptr;
|
||||
|
||||
UnInitialize(oldPtr, oldDeleter);
|
||||
DeleteReferenceIfNeeded(oldPtr, oldDeleter);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Conversion to a ReferenceCountedSharedPtr instance of a base type
|
||||
template <typename Base, typename std::enable_if<std::is_base_of<Base, T>::value>::type* = nullptr>
|
||||
operator _ReferenceCounterSharedPtr<Base>()
|
||||
operator ReferenceCountedPtr<Base>()
|
||||
{
|
||||
return _ReferenceCounterSharedPtr<Base>(m_objPtr, m_deleter);
|
||||
return ReferenceCountedPtr<Base>(m_objPtr, m_deleter);
|
||||
}
|
||||
|
||||
T* operator->() const
|
||||
|
@ -269,25 +247,25 @@ namespace CNTK
|
|||
}
|
||||
|
||||
private:
|
||||
void Init()
|
||||
void AddReferenceIfNeeded()
|
||||
{
|
||||
static_assert(std::is_base_of<_ReferenceCounter, T>::value, "_ReferenceCounterSharedPtr<T> can only be used when _ReferenceCounter is a base type of T!");
|
||||
static_assert(std::is_base_of<ReferenceCount, T>::value, "ReferenceCountedPtr<T> can only be used when ReferenceCount is a base type of T!");
|
||||
|
||||
if (m_objPtr != nullptr)
|
||||
reinterpret_cast<_ReferenceCounter*>(m_objPtr)->AddReference();
|
||||
reinterpret_cast<ReferenceCount*>(m_objPtr)->AddReference();
|
||||
}
|
||||
|
||||
static void UnInitialize(T* objPtr, _ReferenceCounterDeleter deleter)
|
||||
static void DeleteReferenceIfNeeded(T* objPtr, ReferenceCountedObjectDeleter deleter)
|
||||
{
|
||||
static_assert(std::is_base_of<_ReferenceCounter, T>::value, "_ReferenceCounterSharedPtr<T> can only be used when _ReferenceCounter is a base type of T!");
|
||||
static_assert(std::is_base_of<ReferenceCount, T>::value, "ReferenceCountedPtr<T> can only be used when ReferenceCount is a base type of T!");
|
||||
|
||||
if (objPtr != nullptr)
|
||||
{
|
||||
size_t refCountRemaining = reinterpret_cast<_ReferenceCounter*>(objPtr)->RemoveReference();
|
||||
size_t refCountRemaining = reinterpret_cast<ReferenceCount*>(objPtr)->RemoveReference();
|
||||
if (refCountRemaining == 0)
|
||||
{
|
||||
if (deleter != nullptr)
|
||||
deleter(reinterpret_cast<_ReferenceCounter*>(objPtr));
|
||||
deleter(reinterpret_cast<ReferenceCount*>(objPtr));
|
||||
else
|
||||
delete objPtr;
|
||||
}
|
||||
|
@ -296,35 +274,45 @@ namespace CNTK
|
|||
|
||||
private:
|
||||
T* m_objPtr;
|
||||
_ReferenceCounterDeleter m_deleter;
|
||||
ReferenceCountedObjectDeleter m_deleter;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
bool operator==(const _ReferenceCounterSharedPtr<T>& first, const _ReferenceCounterSharedPtr<T>& second)
|
||||
bool operator==(const ReferenceCountedPtr<T>& first, const ReferenceCountedPtr<T>& second)
|
||||
{
|
||||
return first.GetPtr() == second.GetPtr();
|
||||
}
|
||||
|
||||
// A simple vector implementation with a C ABI to allow usage across the library DLL boundary
|
||||
// A wrapper around the STL vector implementation with a safe ABI to allow usage across the library DLL boundary
|
||||
// as STL vectors cannot be used across the DLL boundary
|
||||
template <typename T>
|
||||
class CNTK_API _SimpleVector final
|
||||
class CNTK_API SimpleVector final
|
||||
{
|
||||
template <typename ValueType>
|
||||
friend CNTK_API bool operator==(const _SimpleVector<ValueType>& first, const _SimpleVector<ValueType>& second);
|
||||
friend CNTK_API bool operator==(const SimpleVector<ValueType>& first, const SimpleVector<ValueType>& second);
|
||||
|
||||
friend class CNTK::Function;
|
||||
|
||||
public:
|
||||
_SimpleVector();
|
||||
_SimpleVector(size_t numElements, const T& initVal = T());
|
||||
~_SimpleVector();
|
||||
SimpleVector();
|
||||
|
||||
_SimpleVector(const _SimpleVector& other);
|
||||
_SimpleVector& operator=(const _SimpleVector& other);
|
||||
template <typename ContainerType, typename std::enable_if<std::is_same<ContainerType, std::vector<T>>::value ||
|
||||
std::is_same<ContainerType, std::initializer_list<T>>::value ||
|
||||
std::is_same<ContainerType, std::array<T, sizeof(ContainerType) / sizeof(T)>>::value>::type* = nullptr>
|
||||
SimpleVector(const ContainerType& initList)
|
||||
: SimpleVector(initList.size())
|
||||
{
|
||||
std::copy(initList.begin(), initList.end(), Data());
|
||||
}
|
||||
|
||||
_SimpleVector(_SimpleVector&& other);
|
||||
_SimpleVector& operator=(_SimpleVector&& other);
|
||||
SimpleVector(size_t numElements, const T& initVal = T());
|
||||
~SimpleVector();
|
||||
|
||||
SimpleVector(const SimpleVector& other);
|
||||
SimpleVector& operator=(const SimpleVector& other);
|
||||
|
||||
SimpleVector(SimpleVector&& other);
|
||||
SimpleVector& operator=(SimpleVector&& other);
|
||||
|
||||
T& operator[](size_t idx);
|
||||
const T& operator[](size_t idx) const;
|
||||
|
@ -353,73 +341,62 @@ namespace CNTK
|
|||
{
|
||||
auto insertRet = retSet.insert(this->operator[](i));
|
||||
if (ensureUnique && !insertRet.second)
|
||||
RuntimeError("A _SimpleVector with duplicate elements cannot be converted to an unordered_set");
|
||||
RuntimeError("A SimpleVector with duplicate elements cannot be converted to an unordered_set");
|
||||
}
|
||||
|
||||
return retSet;
|
||||
}
|
||||
|
||||
template <typename ContainerType, typename std::enable_if<std::is_same<ContainerType, std::vector<T>>::value ||
|
||||
std::is_same<ContainerType, std::initializer_list<T>>::value ||
|
||||
std::is_same<ContainerType, std::array<T, sizeof(ContainerType) / sizeof(T)>>::value>::type* = nullptr>
|
||||
static _SimpleVector<T> CreateSimpleVector(const ContainerType& initList)
|
||||
{
|
||||
_SimpleVector<T> simpleVector(initList.size());
|
||||
std::copy(initList.begin(), initList.end(), simpleVector.Data());
|
||||
|
||||
return simpleVector;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<T>* m_vector;
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
CNTK_API bool operator==(const _SimpleVector<ValueType>& first, const _SimpleVector<ValueType>& second);
|
||||
CNTK_API bool operator==(const SimpleVector<ValueType>& first, const SimpleVector<ValueType>& second);
|
||||
|
||||
template <typename ValueType>
|
||||
bool operator!=(const _SimpleVector<ValueType>& first, const _SimpleVector<ValueType>& second)
|
||||
bool operator!=(const SimpleVector<ValueType>& first, const SimpleVector<ValueType>& second)
|
||||
{
|
||||
return !(first == second);
|
||||
}
|
||||
|
||||
// A simple set implementation with a C ABI to allow usage across the library DLL boundary
|
||||
// A wrapper around the STL set implementation with a safe ABI to allow usage across the library DLL boundary
|
||||
// as STL sets cannot be used across the DLL boundary
|
||||
template <typename KeyType>
|
||||
class CNTK_API _SimpleSet final
|
||||
class CNTK_API SimpleSet final
|
||||
{
|
||||
friend class CNTK::CompositeFunction;
|
||||
|
||||
template <typename T>
|
||||
friend CNTK_API bool operator==(const _SimpleSet<T>& first, const _SimpleSet<T>& second);
|
||||
friend CNTK_API bool operator==(const SimpleSet<T>& first, const SimpleSet<T>& second);
|
||||
|
||||
public:
|
||||
_SimpleSet();
|
||||
~_SimpleSet();
|
||||
SimpleSet();
|
||||
~SimpleSet();
|
||||
|
||||
_SimpleSet(const _SimpleSet& other);
|
||||
_SimpleSet& operator=(const _SimpleSet& other);
|
||||
SimpleSet(const SimpleSet& other);
|
||||
SimpleSet& operator=(const SimpleSet& other);
|
||||
|
||||
_SimpleSet(_SimpleSet&& other);
|
||||
_SimpleSet& operator=(_SimpleSet&& other);
|
||||
SimpleSet(SimpleSet&& other);
|
||||
SimpleSet& operator=(SimpleSet&& other);
|
||||
|
||||
bool Insert(const KeyType& key);
|
||||
bool Contains(const KeyType& key) const;
|
||||
|
||||
size_t Size() const;
|
||||
|
||||
operator _SimpleVector<KeyType>() const;
|
||||
operator SimpleVector<KeyType>() const;
|
||||
|
||||
operator std::unordered_set<KeyType>() const
|
||||
{
|
||||
return ((_SimpleVector<KeyType>)(*this)).GetAsUnorderedSet();
|
||||
return ((SimpleVector<KeyType>)(*this)).GetAsUnorderedSet();
|
||||
}
|
||||
|
||||
static _SimpleSet<KeyType> CreateSimpleSet(const std::unordered_set<KeyType>& initSet)
|
||||
static SimpleSet<KeyType> CreateSimpleSet(const std::unordered_set<KeyType>& initSet)
|
||||
{
|
||||
_SimpleSet<KeyType> simpleSet;
|
||||
for (auto iter = initSet.begin(); iter != initSet.end(); ++iter)
|
||||
simpleSet.Insert(*iter);
|
||||
SimpleSet<KeyType> simpleSet;
|
||||
for (auto key : initSet)
|
||||
simpleSet.Insert(key);
|
||||
|
||||
return simpleSet;
|
||||
}
|
||||
|
@ -429,31 +406,31 @@ namespace CNTK
|
|||
};
|
||||
|
||||
template <typename KeyType>
|
||||
CNTK_API bool operator==(const _SimpleSet<KeyType>& first, const _SimpleSet<KeyType>& second);
|
||||
CNTK_API bool operator==(const SimpleSet<KeyType>& first, const SimpleSet<KeyType>& second);
|
||||
|
||||
template <typename KeyType>
|
||||
bool operator!=(const _SimpleSet<KeyType>& first, const _SimpleSet<KeyType>& second)
|
||||
bool operator!=(const SimpleSet<KeyType>& first, const SimpleSet<KeyType>& second)
|
||||
{
|
||||
return !(first == second);
|
||||
}
|
||||
|
||||
// A simple map implementation with a C ABI to allow usage across the library DLL boundary
|
||||
// A wrapper aroound the STL map implementation with a safe ABI to allow usage across the library DLL boundary
|
||||
// as STL maps cannot be used across the DLL boundary
|
||||
template <typename KeyType, typename ValueType>
|
||||
class CNTK_API _SimpleMap final
|
||||
class CNTK_API SimpleMap final
|
||||
{
|
||||
friend class CNTK::CompositeFunction;
|
||||
friend class CNTK::Function;
|
||||
|
||||
public:
|
||||
_SimpleMap();
|
||||
~_SimpleMap();
|
||||
SimpleMap();
|
||||
~SimpleMap();
|
||||
|
||||
_SimpleMap(const _SimpleMap& other);
|
||||
_SimpleMap& operator=(const _SimpleMap& other);
|
||||
SimpleMap(const SimpleMap& other);
|
||||
SimpleMap& operator=(const SimpleMap& other);
|
||||
|
||||
_SimpleMap(_SimpleMap&& other);
|
||||
_SimpleMap& operator=(_SimpleMap&& other);
|
||||
SimpleMap(SimpleMap&& other);
|
||||
SimpleMap& operator=(SimpleMap&& other);
|
||||
|
||||
ValueType& operator[](const KeyType& key);
|
||||
const ValueType& operator[](const KeyType& key) const;
|
||||
|
@ -462,13 +439,13 @@ namespace CNTK
|
|||
bool Contains(const KeyType& key) const;
|
||||
size_t Size() const;
|
||||
|
||||
_SimpleSet<KeyType> Keys() const;
|
||||
SimpleSet<KeyType> Keys() const;
|
||||
|
||||
static _SimpleMap<KeyType, ValueType> CreateSimpleMap(const std::unordered_map<KeyType, ValueType>& initMap)
|
||||
static SimpleMap<KeyType, ValueType> CreateSimpleMap(const std::unordered_map<KeyType, ValueType>& initMap)
|
||||
{
|
||||
_SimpleMap<KeyType, ValueType> simpleMap;
|
||||
for (auto iter = initMap.begin(); iter != initMap.end(); ++iter)
|
||||
simpleMap.Insert(iter->first, iter->second);
|
||||
SimpleMap<KeyType, ValueType> simpleMap;
|
||||
for (auto keyValuePair : initMap)
|
||||
simpleMap.Insert(keyValuePair.first, keyValuePair.second);
|
||||
|
||||
return simpleMap;
|
||||
}
|
||||
|
@ -480,35 +457,28 @@ namespace CNTK
|
|||
|
||||
// Forward declarations
|
||||
class NDArrayView;
|
||||
typedef _Internal::_ReferenceCounterSharedPtr<NDArrayView> NDArrayViewPtr;
|
||||
typedef Internal::ReferenceCountedPtr<NDArrayView> NDArrayViewPtr;
|
||||
|
||||
class NDMask;
|
||||
typedef _Internal::_ReferenceCounterSharedPtr<NDMask> NDMaskPtr;
|
||||
typedef Internal::ReferenceCountedPtr<NDMask> NDMaskPtr;
|
||||
|
||||
class Value;
|
||||
typedef _Internal::_ReferenceCounterSharedPtr<Value> ValuePtr;
|
||||
typedef Internal::ReferenceCountedPtr<Value> ValuePtr;
|
||||
|
||||
class Function;
|
||||
typedef _Internal::_ReferenceCounterSharedPtr<Function> FunctionPtr;
|
||||
typedef Internal::ReferenceCountedPtr<Function> FunctionPtr;
|
||||
|
||||
inline wchar_t* CopyString(const wchar_t* source)
|
||||
namespace Internal
|
||||
{
|
||||
size_t len = wcslen(source) + 1;
|
||||
wchar_t* copy = new wchar_t[len];
|
||||
#ifdef _WIN32
|
||||
wcscpy_s(copy, len, source);
|
||||
#else
|
||||
wcscpy(copy, source);
|
||||
#endif
|
||||
return copy;
|
||||
CNTK_API FunctionPtr Combine(const Internal::SimpleVector<FunctionPtr>& operands, const std::wstring& name = L"");
|
||||
}
|
||||
}
|
||||
|
||||
namespace std {
|
||||
template <typename T>
|
||||
struct hash<CNTK::_Internal::_ReferenceCounterSharedPtr<T>>
|
||||
struct hash<CNTK::Internal::ReferenceCountedPtr<T>>
|
||||
{
|
||||
size_t operator()(const CNTK::_Internal::_ReferenceCounterSharedPtr<T>& x) const
|
||||
size_t operator()(const CNTK::Internal::ReferenceCountedPtr<T>& x) const
|
||||
{
|
||||
return std::hash<const void*>()(x.GetPtr());
|
||||
}
|
||||
|
|
|
@ -17,40 +17,50 @@ bool g_shareNodeValueMatrices = true;
|
|||
|
||||
namespace CNTK
|
||||
{
|
||||
_Internal::_SimpleVector<Variable> Function::_Inputs() const
|
||||
Internal::SimpleVector<Variable> Function::InputsImpl() const
|
||||
{
|
||||
const CompositeFunction* compositeFunction = dynamic_cast<const CompositeFunction*>(this);
|
||||
if (compositeFunction == nullptr)
|
||||
return m_inputs;
|
||||
else
|
||||
return _Internal::_SimpleVector<Variable>::CreateSimpleVector(compositeFunction->DetermineInputs());
|
||||
return Internal::SimpleVector<Variable>(compositeFunction->DetermineInputs());
|
||||
}
|
||||
|
||||
/*virtual*/ void Function::_ReplacePlaceholders(const _Internal::_SimpleMap<Placeholder, Variable>& placeholderReplacements, _Internal::_SimpleSet<const Function*>& visitedFunctions, _Internal::_SimpleSet<Placeholder>& replacedPlaceholders)
|
||||
/*virtual*/ void Function::_ReplacePlaceholders(const Internal::SimpleMap<Placeholder, Variable>& placeholderReplacements,
|
||||
Internal::SimpleSet<const Function*>& visitedFunctions,
|
||||
Internal::SimpleSet<Placeholder>& replacedPlaceholders)
|
||||
{
|
||||
visitedFunctions.Insert(this);
|
||||
|
||||
for (auto iter = m_inputs.m_vector->begin(); iter != m_inputs.m_vector->end(); ++iter)
|
||||
for (auto& inputVar : *(m_inputs.m_vector))
|
||||
{
|
||||
if (iter->IsPlaceholder())
|
||||
if (inputVar.IsPlaceholder())
|
||||
{
|
||||
Placeholder placeholder(*iter);
|
||||
Placeholder placeholder(inputVar);
|
||||
if (placeholderReplacements.Contains(placeholder))
|
||||
{
|
||||
*iter = placeholderReplacements[placeholder];
|
||||
inputVar = placeholderReplacements[placeholder];
|
||||
replacedPlaceholders.Insert(placeholder);
|
||||
}
|
||||
}
|
||||
else if ((iter->Kind() == VariableKind::Output) && !visitedFunctions.Contains(iter->Owner()))
|
||||
iter->Owner()->_ReplacePlaceholders(placeholderReplacements, visitedFunctions, replacedPlaceholders);
|
||||
else if (inputVar.IsOutput() && !visitedFunctions.Contains(inputVar.Owner()))
|
||||
inputVar.Owner()->_ReplacePlaceholders(placeholderReplacements, visitedFunctions, replacedPlaceholders);
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively create a sub-network of ComputationNode instances corresponding to the graph of Functions
|
||||
// underlying the specified 'variable' and return the ComputationNode instance that corresponds to the
|
||||
// top level 'variable'
|
||||
template <typename ElementType>
|
||||
/*static*/ ComputationNodeBasePtr CompositeFunction::GetNode(const Variable& variable, Microsoft::MSR::CNTK::ComputationNetworkPtr& network, ComputationNetworkBuilder<ElementType>& builder, std::unordered_map<Variable, ComputationNodeBasePtr>& variableToNodeMap, std::unordered_map<Variable, bool>& isVariableRootMap)
|
||||
/*static*/ ComputationNodeBasePtr CompositeFunction::GetNode(const Variable& variable,
|
||||
Microsoft::MSR::CNTK::ComputationNetworkPtr& network,
|
||||
ComputationNetworkBuilder<ElementType>& builder,
|
||||
std::unordered_map<Variable, ComputationNodeBasePtr>& variableToNodeMap,
|
||||
std::unordered_map<Variable, bool>& isVariableRootMap)
|
||||
{
|
||||
if (variableToNodeMap.find(variable) != variableToNodeMap.end())
|
||||
return variableToNodeMap[variable];
|
||||
auto iter = variableToNodeMap.find(variable);
|
||||
if (iter != variableToNodeMap.end())
|
||||
return iter->second;
|
||||
|
||||
// Lets add a null entry in the map for this variable, to break infinite recursion when processing recurrent graphs
|
||||
variableToNodeMap[variable] = nullptr;
|
||||
|
@ -66,7 +76,7 @@ namespace CNTK
|
|||
auto matrix = variable.IsConstant() ? value->GetMatrix<ElementType>()->AsReference() : value->GetWritableMatrix<ElementType>()->AsReference();
|
||||
computationNodePtr->Value() = std::move(matrix);
|
||||
}
|
||||
else if (variable.Kind() == VariableKind::Input)
|
||||
else if (variable.IsInput())
|
||||
{
|
||||
// TODO: Specify dynamic axis
|
||||
if (variable.IsSparseInput())
|
||||
|
@ -83,23 +93,27 @@ namespace CNTK
|
|||
}
|
||||
else
|
||||
{
|
||||
assert(variable.Kind() == VariableKind::Output);
|
||||
assert(variable.IsOutput());
|
||||
computationNodePtr = GetOutputVariableNode(variable, network, builder, variableToNodeMap, isVariableRootMap)->template As<ComputationNode<ElementType>>()->shared_from_this();
|
||||
}
|
||||
|
||||
variableToNodeMap[variable] = computationNodePtr;
|
||||
isVariableRootMap[variable] = (variable.Kind() == VariableKind::Output);
|
||||
isVariableRootMap[variable] = variable.IsOutput();
|
||||
return computationNodePtr;
|
||||
}
|
||||
|
||||
template <typename ElementType>
|
||||
/*static*/ ComputationNodeBasePtr CompositeFunction::GetOutputVariableNode(const Variable& variable, Microsoft::MSR::CNTK::ComputationNetworkPtr& network, ComputationNetworkBuilder<ElementType>& builder, std::unordered_map<Variable, ComputationNodeBasePtr>& variableToNodeMap, std::unordered_map<Variable, bool>& isVariableRootMap)
|
||||
/*static*/ ComputationNodeBasePtr CompositeFunction::GetOutputVariableNode(const Variable& variable,
|
||||
Microsoft::MSR::CNTK::ComputationNetworkPtr& network,
|
||||
ComputationNetworkBuilder<ElementType>& builder,
|
||||
std::unordered_map<Variable, ComputationNodeBasePtr>& variableToNodeMap,
|
||||
std::unordered_map<Variable, bool>& isVariableRootMap)
|
||||
{
|
||||
assert(variable.Kind() == VariableKind::Output);
|
||||
assert(variable.IsOutput());
|
||||
|
||||
Function* function = variable.Owner();
|
||||
ComputationNodeBasePtr computationNodePtr;
|
||||
if (dynamic_cast<PrimitiveFunction*>(function) != nullptr)
|
||||
if (dynamic_cast<PrimitiveFunction*>(function))
|
||||
{
|
||||
PrimitiveFunction* primitiveFunction = dynamic_cast<PrimitiveFunction*>(function);
|
||||
|
||||
|
@ -134,7 +148,7 @@ namespace CNTK
|
|||
case PrimitiveOpType::CrossEntropyWithSoftmax:
|
||||
computationNodePtr = builder.CrossEntropyWithSoftmax(input1Node, input0Node, function->Name());
|
||||
break;
|
||||
case PrimitiveOpType::PredictionError:
|
||||
case PrimitiveOpType::ClassificationError:
|
||||
computationNodePtr = builder.ErrorPrediction(input1Node, input0Node, function->Name());
|
||||
break;
|
||||
case PrimitiveOpType::Exp:
|
||||
|
@ -180,8 +194,10 @@ namespace CNTK
|
|||
break;
|
||||
}
|
||||
case PrimitiveOpType::Combine:
|
||||
for (size_t i = 0; i < functionInputs.size(); ++i)
|
||||
GetNode(functionInputs[i], network, builder, variableToNodeMap, isVariableRootMap);
|
||||
// This operation is just a no-op and is a means to combine multiple functions to create a single Function
|
||||
// whose outputs are a union of tyhe outputs of the Functions being combined.
|
||||
for (auto inputVar : functionInputs)
|
||||
GetNode(inputVar, network, builder, variableToNodeMap, isVariableRootMap);
|
||||
|
||||
computationNodePtr = variableToNodeMap[variable];
|
||||
|
||||
|
@ -193,8 +209,8 @@ namespace CNTK
|
|||
|
||||
if (op != PrimitiveOpType::Combine)
|
||||
{
|
||||
for (size_t i = 0; i < functionInputs.size(); ++i)
|
||||
isVariableRootMap[functionInputs[i]] = false;
|
||||
for (auto inputVar : functionInputs)
|
||||
isVariableRootMap[inputVar] = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -206,7 +222,7 @@ namespace CNTK
|
|||
}
|
||||
|
||||
template <typename ElementType>
|
||||
ComputationNetworkPtr CompositeFunction::GetComputationNetwork(const DeviceDescriptor& device, const _Internal::_SimpleSet<Variable>& backpropRoots)
|
||||
ComputationNetworkPtr CompositeFunction::GetComputationNetwork(const DeviceDescriptor& device, const Internal::SimpleSet<Variable>& backpropRoots)
|
||||
{
|
||||
if (m_computationNetwork != nullptr)
|
||||
{
|
||||
|
@ -237,52 +253,52 @@ namespace CNTK
|
|||
auto rootFunction = RootFunction();
|
||||
auto rootFunctionOutputs = rootFunction->Outputs();
|
||||
std::vector<ComputationNodeBasePtr> forwardRootNodes;
|
||||
for (size_t i = 0; i < rootFunctionOutputs.size(); ++i)
|
||||
for (auto rootOutput : rootFunctionOutputs)
|
||||
{
|
||||
auto currentRootNode = GetNode(rootFunctionOutputs[i], m_computationNetwork, builder, m_variableToNodeMap, m_isVariableRootMap);
|
||||
auto currentRootNode = GetNode(rootOutput, m_computationNetwork, builder, m_variableToNodeMap, m_isVariableRootMap);
|
||||
forwardRootNodes.push_back(currentRootNode);
|
||||
|
||||
if (backpropRoots.Contains(rootFunctionOutputs[i]))
|
||||
backpropRootNode = m_variableToNodeMap[rootFunctionOutputs[i]];
|
||||
if (backpropRoots.Contains(rootOutput))
|
||||
backpropRootNode = m_variableToNodeMap[rootOutput];
|
||||
}
|
||||
|
||||
// If any of the function outputs is not a root node, we need to explicitly add it to the 'output' group of the ComputationNetwork
|
||||
for (size_t i = 0; i < rootFunctionOutputs.size(); ++i)
|
||||
for (auto rootOutput : rootFunctionOutputs)
|
||||
{
|
||||
if (!m_isVariableRootMap[rootFunctionOutputs[i]])
|
||||
m_computationNetwork->AddToNodeGroup(L"output", m_variableToNodeMap[rootFunctionOutputs[i]]);
|
||||
if (!m_isVariableRootMap[rootOutput])
|
||||
m_computationNetwork->AddToNodeGroup(L"output", m_variableToNodeMap[rootOutput]);
|
||||
}
|
||||
|
||||
m_currentBackpropRoots = backpropRoots;
|
||||
|
||||
// In case of recurrence, the inputs of some of the ComputationNodes are not attached due to cycles.
|
||||
// Now attach those after we have created all ComputationNodes in the network
|
||||
for (auto iter = m_variableToNodeMap.begin(); iter != m_variableToNodeMap.end(); ++iter)
|
||||
for (auto varNodePair : m_variableToNodeMap)
|
||||
{
|
||||
auto currentComputationNodeInputs = iter->second->GetInputs();
|
||||
auto currentComputationNodeInputs = varNodePair.second->GetInputs();
|
||||
|
||||
// TODO: Can any node other than a non PastValue/FutureValue Function have a null input attached after the first pass is finished?
|
||||
if (std::find(currentComputationNodeInputs.begin(), currentComputationNodeInputs.end(), nullptr) != currentComputationNodeInputs.end())
|
||||
{
|
||||
// We found a null input; this variable must correspond to a PastValue or FutureValue function
|
||||
const PrimitiveFunction* primitiveFunc = dynamic_cast<const PrimitiveFunction*>(iter->first.Owner().GetPtr());
|
||||
const PrimitiveFunction* primitiveFunc = dynamic_cast<const PrimitiveFunction*>(varNodePair.first.Owner().GetPtr());
|
||||
if ((primitiveFunc == nullptr) || ((primitiveFunc->OpType() != PrimitiveOpType::PastValue) && (primitiveFunc->OpType() != PrimitiveOpType::FutureValue)))
|
||||
InvalidArgument("Invalid Function graph detected; recurrence found at a Function that is not a PastValue/FutureValue function");
|
||||
|
||||
// The 2nd input of the PastValue/FutureValue function denotes the recurrent input
|
||||
auto actualInput = m_variableToNodeMap[primitiveFunc->Inputs()[1]];
|
||||
iter->second->AttachInputs({ actualInput });
|
||||
varNodePair.second->AttachInputs({ actualInput });
|
||||
}
|
||||
}
|
||||
|
||||
m_computationNetwork->CompileNetwork();
|
||||
|
||||
// Verify that the shapes of the output Variables that we computed match the corresponding nodes in the ComputationNetwork
|
||||
for (auto iter = m_variableToNodeMap.begin(); iter != m_variableToNodeMap.end(); ++iter)
|
||||
for (auto varNodePair : m_variableToNodeMap)
|
||||
{
|
||||
if (iter->first.Kind() == VariableKind::Output)
|
||||
if (varNodePair.first.IsOutput())
|
||||
{
|
||||
auto outputVar = iter->first;
|
||||
auto outputVar = varNodePair.first;
|
||||
auto computationNodePtr = m_variableToNodeMap[outputVar];
|
||||
auto outputShape = outputVar.Shape();
|
||||
auto computationNodeSampleLayout = computationNodePtr->GetSampleLayout();
|
||||
|
@ -442,8 +458,8 @@ namespace CNTK
|
|||
{
|
||||
// Just create a view over the existing matrix itself
|
||||
auto tensorView = new TensorView<ElementType>(std::make_shared<Matrix<ElementType>>(matrix.AsReference()), AsTensorShape(valueDataShape));
|
||||
auto data = NDArrayViewPtr(new NDArrayView(AsDataType<ElementType>(), AsDeviceDescriptor(matrix.GetDeviceId()), AsStorageFormat(matrix.GetFormat()), valueDataShape, true, tensorView), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
return ValuePtr(new Value(data), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
auto data = NDArrayViewPtr(new NDArrayView(AsDataType<ElementType>(), AsDeviceDescriptor(matrix.GetDeviceId()), AsStorageFormat(matrix.GetFormat()), valueDataShape, true, tensorView), [](ReferenceCount* ptr) { delete ptr; });
|
||||
return ValuePtr(new Value(data), [](ReferenceCount* ptr) { delete ptr; });
|
||||
}
|
||||
|
||||
if (layout->GetNumCols() != matrix.GetNumCols())
|
||||
|
@ -454,10 +470,10 @@ namespace CNTK
|
|||
|
||||
std::vector<size_t> sequenceLengths;
|
||||
auto& layoutSequences = layout->GetAllSequences();
|
||||
for (auto iter = layoutSequences.begin(); iter != layoutSequences.end(); ++iter)
|
||||
for (auto sequenceInfo : layoutSequences)
|
||||
{
|
||||
if (iter->seqId != GAP_SEQUENCE_ID)
|
||||
sequenceLengths.push_back(iter->GetNumTimeSteps());
|
||||
if (sequenceInfo.seqId != GAP_SEQUENCE_ID)
|
||||
sequenceLengths.push_back(sequenceInfo.GetNumTimeSteps());
|
||||
}
|
||||
|
||||
// Reshuffle to data to unpack and uninterleave the CNTK form data
|
||||
|
@ -473,13 +489,13 @@ namespace CNTK
|
|||
size_t targetColIdxForInvalidColumns = sequencesShorterThanLongestSequence.empty() ? 0 : (((sequencesShorterThanLongestSequence[0] + 1) * maxNumTimeSteps) - 1);
|
||||
std::vector<ElementType> scatterIndicesVector(layout->GetNumCols(), (ElementType)targetColIdxForInvalidColumns);
|
||||
size_t i = 0;
|
||||
for (auto iter = layoutSequences.begin(); iter != layoutSequences.end(); ++iter)
|
||||
for (auto sequenceInfo : layoutSequences)
|
||||
{
|
||||
if (iter->seqId != GAP_SEQUENCE_ID)
|
||||
if (sequenceInfo.seqId != GAP_SEQUENCE_ID)
|
||||
{
|
||||
size_t targetParallelStreamIdx = iter->s;
|
||||
size_t targetStartIdxInParallelStream = iter->tBegin;
|
||||
for (size_t j = 0; j < iter->GetNumTimeSteps(); ++j)
|
||||
size_t targetParallelStreamIdx = sequenceInfo.s;
|
||||
size_t targetStartIdxInParallelStream = sequenceInfo.tBegin;
|
||||
for (size_t j = 0; j < sequenceInfo.GetNumTimeSteps(); ++j)
|
||||
scatterIndicesVector[((targetStartIdxInParallelStream + j) * layout->GetNumParallelSequences()) + targetParallelStreamIdx] = (ElementType)((i * maxNumTimeSteps) + j);
|
||||
|
||||
i++;
|
||||
|
@ -493,40 +509,39 @@ namespace CNTK
|
|||
NDMaskPtr mask;
|
||||
if (!sequencesShorterThanLongestSequence.empty())
|
||||
{
|
||||
mask = NDMaskPtr(new NDMask({ maxNumTimeSteps, numSequences }, AsDeviceDescriptor(matrix.GetDeviceId())), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
for (size_t i = 0; i < sequencesShorterThanLongestSequence.size(); ++i)
|
||||
mask = NDMaskPtr(new NDMask({ maxNumTimeSteps, numSequences }, AsDeviceDescriptor(matrix.GetDeviceId())), [](ReferenceCount* ptr) { delete ptr; });
|
||||
for (auto shortSequenceIdx : sequencesShorterThanLongestSequence)
|
||||
{
|
||||
size_t shorterSequenceIdx = sequencesShorterThanLongestSequence[i];
|
||||
mask->MaskSection({ sequenceLengths[shorterSequenceIdx], shorterSequenceIdx }, { NDShape::InferredDimension, 1 });
|
||||
mask->MaskSection({ sequenceLengths[shortSequenceIdx], shortSequenceIdx }, { NDShape::InferredDimension, 1 });
|
||||
}
|
||||
}
|
||||
|
||||
auto tensorView = new TensorView<ElementType>(shuffledMatrixData, AsTensorShape(valueDataShape));
|
||||
auto data = NDArrayViewPtr(new NDArrayView(AsDataType<ElementType>(), AsDeviceDescriptor(matrix.GetDeviceId()), StorageFormat::Dense, valueDataShape, true, tensorView), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
return ValuePtr(new Value(data, mask), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
auto data = NDArrayViewPtr(new NDArrayView(AsDataType<ElementType>(), AsDeviceDescriptor(matrix.GetDeviceId()), StorageFormat::Dense, valueDataShape, true, tensorView), [](ReferenceCount* ptr) { delete ptr; });
|
||||
return ValuePtr(new Value(data, mask), [](ReferenceCount* ptr) { delete ptr; });
|
||||
}
|
||||
|
||||
void CompositeFunction::PopulateNetworkInputs(const _Internal::_SimpleMap<Variable, const ValuePtr>& arguments)
|
||||
void CompositeFunction::PopulateNetworkInputs(const Internal::SimpleMap<Variable, const ValuePtr>& arguments)
|
||||
{
|
||||
auto functionArguments = this->Arguments();
|
||||
std::vector<ComputationNodeBasePtr> inputNodes;
|
||||
for (auto iter = functionArguments.begin(); iter != functionArguments.end(); ++iter)
|
||||
for (auto argument : functionArguments)
|
||||
{
|
||||
// Ensure we have values for all arguments of the function
|
||||
if (!arguments.Contains(*iter))
|
||||
if (!arguments.Contains(argument))
|
||||
InvalidArgument("Value not specified for required Function Argument");
|
||||
|
||||
auto argumentComputationNode = m_variableToNodeMap[*iter];
|
||||
auto argumentComputationNode = m_variableToNodeMap[argument];
|
||||
inputNodes.push_back(argumentComputationNode);
|
||||
|
||||
ValuePtr argumentValue = arguments[*iter];
|
||||
ValuePtr argumentValue = arguments[argument];
|
||||
|
||||
MBLayoutPtr layout;
|
||||
switch (argumentValue->Data()->GetDataType())
|
||||
{
|
||||
case DataType::Float:
|
||||
{
|
||||
auto CNTKMatrixAndMBLayout = GetCNTKImplMatrixAndMBLayoutFromValueObject<float>(*iter, argumentValue);
|
||||
auto CNTKMatrixAndMBLayout = GetCNTKImplMatrixAndMBLayoutFromValueObject<float>(argument, argumentValue);
|
||||
layout = CNTKMatrixAndMBLayout.second;
|
||||
|
||||
auto& nodeData = argumentComputationNode->As<ComputationNode<float>>()->Value();
|
||||
|
@ -537,7 +552,7 @@ namespace CNTK
|
|||
}
|
||||
case DataType::Double:
|
||||
{
|
||||
auto CNTKMatrixAndMBLayout = GetCNTKImplMatrixAndMBLayoutFromValueObject<double>(*iter, argumentValue);
|
||||
auto CNTKMatrixAndMBLayout = GetCNTKImplMatrixAndMBLayoutFromValueObject<double>(argument, argumentValue);
|
||||
layout = CNTKMatrixAndMBLayout.second;
|
||||
|
||||
auto& nodeData = argumentComputationNode->As<ComputationNode<double>>()->Value();
|
||||
|
@ -557,40 +572,40 @@ namespace CNTK
|
|||
m_computationNetwork->BumpEvalTimeStamp(inputNodes);
|
||||
}
|
||||
|
||||
void CompositeFunction::PopulateNetworkGradients(const _Internal::_SimpleMap<Variable, const ValuePtr>& gradients)
|
||||
void CompositeFunction::PopulateNetworkGradients(const Internal::SimpleMap<Variable, const ValuePtr>& gradients)
|
||||
{
|
||||
auto functionOutputs = this->Outputs();
|
||||
std::unordered_map<Variable, const ValuePtr>& gradientsValueMap = *gradients.m_map;
|
||||
for (auto iter = gradientsValueMap.begin(); iter != gradientsValueMap.end(); ++iter)
|
||||
for (auto gradientVarValuePair : gradientsValueMap)
|
||||
{
|
||||
// Only gradients for roots of the function can be specified
|
||||
if (std::find(functionOutputs.begin(), functionOutputs.end(), iter->first) == functionOutputs.end())
|
||||
if (std::find(functionOutputs.begin(), functionOutputs.end(), gradientVarValuePair.first) == functionOutputs.end())
|
||||
InvalidArgument("Gradients cannot be specified for a Variable that is not an Output of the Function");
|
||||
|
||||
auto outputComputationNode = m_variableToNodeMap[iter->first];
|
||||
auto outputComputationNode = m_variableToNodeMap[gradientVarValuePair.first];
|
||||
auto nodeLayout = outputComputationNode->GetMBLayout();
|
||||
|
||||
ValuePtr gradientValue = iter->second;
|
||||
ValuePtr gradientValue = gradientVarValuePair.second;
|
||||
|
||||
MBLayoutPtr layout;
|
||||
switch (gradientValue->Data()->GetDataType())
|
||||
{
|
||||
case DataType::Float:
|
||||
{
|
||||
auto CNTKMatrixAndMBLayout = GetCNTKImplMatrixAndMBLayoutFromValueObject<float>(iter->first, gradientValue);
|
||||
auto CNTKMatrixAndMBLayout = GetCNTKImplMatrixAndMBLayoutFromValueObject<float>(gradientVarValuePair.first, gradientValue);
|
||||
layout = CNTKMatrixAndMBLayout.second;
|
||||
if (((layout == nullptr) != (nodeLayout == nullptr)) || ((layout != nullptr) && (*layout != *nodeLayout)))
|
||||
InvalidArgument("The layout of the specified gradient Value in incompatible with the layout of the corresponding Variable computed during Forward call");
|
||||
outputComputationNode->As<ComputationNode<float>>()->ResetGradient(*CNTKMatrixAndMBLayout.first);
|
||||
outputComputationNode->As<ComputationNode<float>>()->AssignGradient(*CNTKMatrixAndMBLayout.first);
|
||||
break;
|
||||
}
|
||||
case DataType::Double:
|
||||
{
|
||||
auto CNTKMatrixAndMBLayout = GetCNTKImplMatrixAndMBLayoutFromValueObject<double>(iter->first, gradientValue);
|
||||
auto CNTKMatrixAndMBLayout = GetCNTKImplMatrixAndMBLayoutFromValueObject<double>(gradientVarValuePair.first, gradientValue);
|
||||
layout = CNTKMatrixAndMBLayout.second;
|
||||
if (((layout == nullptr) != (nodeLayout == nullptr)) || ((layout != nullptr) && (*layout != *nodeLayout)))
|
||||
InvalidArgument("The layout of the specified gradient Value in incompatible with the layout of the corresponding Variable computed during Forward call");
|
||||
outputComputationNode->As<ComputationNode<double>>()->ResetGradient(*CNTKMatrixAndMBLayout.first);
|
||||
outputComputationNode->As<ComputationNode<double>>()->AssignGradient(*CNTKMatrixAndMBLayout.first);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -622,12 +637,12 @@ namespace CNTK
|
|||
void CompositeFunction::GetNetworkOutputs(std::unordered_map<Variable, ValuePtr>& outputs)
|
||||
{
|
||||
// Now copy the Forward values of output nodes from the network to outputs' Value objects
|
||||
for (auto iter = outputs.begin(); iter != outputs.end(); ++iter)
|
||||
for (auto outputVarValuePair : outputs)
|
||||
{
|
||||
auto computationNodePtr = m_variableToNodeMap[iter->first];
|
||||
auto outputValuePtr = iter->second;
|
||||
auto computationNodePtr = m_variableToNodeMap[outputVarValuePair.first];
|
||||
auto outputValuePtr = outputVarValuePair.second;
|
||||
|
||||
auto outputShape = GetValueShape(iter->first, computationNodePtr);
|
||||
auto outputShape = GetValueShape(outputVarValuePair.first, computationNodePtr);
|
||||
if (outputValuePtr != nullptr)
|
||||
{
|
||||
// TODO: The shape of the specified output Value object must match the actual output shape
|
||||
|
@ -635,38 +650,38 @@ namespace CNTK
|
|||
InvalidArgument("The shape %s of the specified Value object for output does not match the actual output shape %s", AsString(outputValuePtr->Data()->Shape()).c_str(), AsString(outputShape).c_str());
|
||||
}
|
||||
|
||||
switch (iter->first.GetDataType())
|
||||
switch (outputVarValuePair.first.GetDataType())
|
||||
{
|
||||
case DataType::Float:
|
||||
{
|
||||
auto nodeValue = GetValueObjectFromCNTKImplMatrixAndMBLayout<float>(iter->first, computationNodePtr->As<ComputationNode<float>>()->Value(), computationNodePtr->GetMBLayout());
|
||||
auto nodeValue = GetValueObjectFromCNTKImplMatrixAndMBLayout<float>(outputVarValuePair.first, computationNodePtr->As<ComputationNode<float>>()->Value(), computationNodePtr->GetMBLayout());
|
||||
if (outputValuePtr == nullptr)
|
||||
{
|
||||
auto data = NDArrayViewPtr(new NDArrayView(iter->first.GetDataType(), outputShape, AsDeviceDescriptor(computationNodePtr->ValuePtr()->GetDeviceId())), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
auto mask = (nodeValue->Mask() != nullptr) ? NDMaskPtr(new NDMask(nodeValue->Mask()->Shape(), nodeValue->Mask()->Device()), [](_ReferenceCounter* ptr) { delete ptr; }) : nullptr;
|
||||
outputValuePtr = ValuePtr(new Value(data, mask), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
auto data = NDArrayViewPtr(new NDArrayView(outputVarValuePair.first.GetDataType(), outputShape, AsDeviceDescriptor(computationNodePtr->ValuePtr()->GetDeviceId())), [](ReferenceCount* ptr) { delete ptr; });
|
||||
auto mask = (nodeValue->Mask() != nullptr) ? NDMaskPtr(new NDMask(nodeValue->Mask()->Shape(), nodeValue->Mask()->Device()), [](ReferenceCount* ptr) { delete ptr; }) : nullptr;
|
||||
outputValuePtr = ValuePtr(new Value(data, mask), [](ReferenceCount* ptr) { delete ptr; });
|
||||
}
|
||||
outputValuePtr->CopyFrom(*nodeValue);
|
||||
break;
|
||||
}
|
||||
case DataType::Double:
|
||||
{
|
||||
auto nodeValue = GetValueObjectFromCNTKImplMatrixAndMBLayout<double>(iter->first, computationNodePtr->As<ComputationNode<double>>()->Value(), computationNodePtr->GetMBLayout());
|
||||
auto nodeValue = GetValueObjectFromCNTKImplMatrixAndMBLayout<double>(outputVarValuePair.first, computationNodePtr->As<ComputationNode<double>>()->Value(), computationNodePtr->GetMBLayout());
|
||||
if (outputValuePtr == nullptr)
|
||||
{
|
||||
auto data = NDArrayViewPtr(new NDArrayView(iter->first.GetDataType(), outputShape, AsDeviceDescriptor(computationNodePtr->ValuePtr()->GetDeviceId())), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
auto mask = (nodeValue->Mask() != nullptr) ? NDMaskPtr(new NDMask(nodeValue->Mask()->Shape(), nodeValue->Mask()->Device()), [](_ReferenceCounter* ptr) { delete ptr; }) : nullptr;
|
||||
outputValuePtr = ValuePtr(new Value(data, mask), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
auto data = NDArrayViewPtr(new NDArrayView(outputVarValuePair.first.GetDataType(), outputShape, AsDeviceDescriptor(computationNodePtr->ValuePtr()->GetDeviceId())), [](ReferenceCount* ptr) { delete ptr; });
|
||||
auto mask = (nodeValue->Mask() != nullptr) ? NDMaskPtr(new NDMask(nodeValue->Mask()->Shape(), nodeValue->Mask()->Device()), [](ReferenceCount* ptr) { delete ptr; }) : nullptr;
|
||||
outputValuePtr = ValuePtr(new Value(data, mask), [](ReferenceCount* ptr) { delete ptr; });
|
||||
}
|
||||
outputValuePtr->CopyFrom(*nodeValue);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LogicError("Unsupported DataType %s", DataTypeName(iter->first.GetDataType()));
|
||||
LogicError("Unsupported DataType %s", DataTypeName(outputVarValuePair.first.GetDataType()));
|
||||
break;
|
||||
}
|
||||
|
||||
outputs[iter->first] = outputValuePtr;
|
||||
outputs[outputVarValuePair.first] = outputValuePtr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -674,20 +689,20 @@ namespace CNTK
|
|||
{
|
||||
auto networkInputs = this->Inputs();
|
||||
// Now copy the gradient values of input nodes of the network to gradients' Value objects
|
||||
for (auto iter = gradients.begin(); iter != gradients.end(); ++iter)
|
||||
for (auto gradientVarValuePair : gradients)
|
||||
{
|
||||
// Only gradients corresponding to inputs of the network can be obtained
|
||||
if (std::find(networkInputs.begin(), networkInputs.end(), iter->first) == networkInputs.end())
|
||||
if (std::find(networkInputs.begin(), networkInputs.end(), gradientVarValuePair.first) == networkInputs.end())
|
||||
InvalidArgument("Backpropagated gradient values can only be obtained for inputs of a Function");
|
||||
|
||||
// Gradients can only be obtained for parameter variables or input variables that NeedsGradient
|
||||
if (!iter->first.NeedsGradient())
|
||||
if (!gradientVarValuePair.first.NeedsGradient())
|
||||
InvalidArgument("Gradient value incorrectly requested for an Output or Constant Variable, or an Input Variable with NeedsGradient setting of false");
|
||||
|
||||
auto computationNodePtr = m_variableToNodeMap[iter->first];
|
||||
auto gradientValuePtr = iter->second;
|
||||
auto computationNodePtr = m_variableToNodeMap[gradientVarValuePair.first];
|
||||
auto gradientValuePtr = gradientVarValuePair.second;
|
||||
|
||||
auto gradientShape = GetValueShape(iter->first, computationNodePtr);
|
||||
auto gradientShape = GetValueShape(gradientVarValuePair.first, computationNodePtr);
|
||||
if (gradientValuePtr != nullptr)
|
||||
{
|
||||
// TODO: The shape of the specified output Value object must match the actual output shape
|
||||
|
@ -698,45 +713,45 @@ namespace CNTK
|
|||
if (!computationNodePtr->NeedsGradient())
|
||||
LogicError("Backpropagated gradient value cannot be read from a ComputationNode that has NeedsGradient set to false");
|
||||
|
||||
switch (iter->first.GetDataType())
|
||||
switch (gradientVarValuePair.first.GetDataType())
|
||||
{
|
||||
case DataType::Float:
|
||||
{
|
||||
auto nodeValue = GetValueObjectFromCNTKImplMatrixAndMBLayout<float>(iter->first, computationNodePtr->As<ComputationNode<float>>()->Gradient(), computationNodePtr->GetMBLayout());
|
||||
auto nodeValue = GetValueObjectFromCNTKImplMatrixAndMBLayout<float>(gradientVarValuePair.first, computationNodePtr->As<ComputationNode<float>>()->Gradient(), computationNodePtr->GetMBLayout());
|
||||
if (gradientValuePtr == nullptr)
|
||||
{
|
||||
auto data = NDArrayViewPtr(new NDArrayView(iter->first.GetDataType(), gradientShape, AsDeviceDescriptor(computationNodePtr->ValuePtr()->GetDeviceId())), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
auto mask = NDMaskPtr((nodeValue->Mask() != nullptr) ? new NDMask(nodeValue->Mask()->Shape(), nodeValue->Mask()->Device()) : nullptr, [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
gradientValuePtr = ValuePtr(new Value(data, mask), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
auto data = NDArrayViewPtr(new NDArrayView(gradientVarValuePair.first.GetDataType(), gradientShape, AsDeviceDescriptor(computationNodePtr->ValuePtr()->GetDeviceId())), [](ReferenceCount* ptr) { delete ptr; });
|
||||
auto mask = NDMaskPtr((nodeValue->Mask() != nullptr) ? new NDMask(nodeValue->Mask()->Shape(), nodeValue->Mask()->Device()) : nullptr, [](ReferenceCount* ptr) { delete ptr; });
|
||||
gradientValuePtr = ValuePtr(new Value(data, mask), [](ReferenceCount* ptr) { delete ptr; });
|
||||
}
|
||||
gradientValuePtr->CopyFrom(*nodeValue);
|
||||
break;
|
||||
}
|
||||
case DataType::Double:
|
||||
{
|
||||
auto nodeValue = GetValueObjectFromCNTKImplMatrixAndMBLayout<double>(iter->first, computationNodePtr->As<ComputationNode<double>>()->Gradient(), computationNodePtr->GetMBLayout());
|
||||
auto nodeValue = GetValueObjectFromCNTKImplMatrixAndMBLayout<double>(gradientVarValuePair.first, computationNodePtr->As<ComputationNode<double>>()->Gradient(), computationNodePtr->GetMBLayout());
|
||||
if (gradientValuePtr == nullptr)
|
||||
{
|
||||
auto data = NDArrayViewPtr(new NDArrayView(iter->first.GetDataType(), gradientShape, AsDeviceDescriptor(computationNodePtr->ValuePtr()->GetDeviceId())), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
auto mask = NDMaskPtr((nodeValue->Mask() != nullptr) ? new NDMask(nodeValue->Mask()->Shape(), nodeValue->Mask()->Device()) : nullptr, [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
gradientValuePtr = ValuePtr(new Value(data, mask), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
auto data = NDArrayViewPtr(new NDArrayView(gradientVarValuePair.first.GetDataType(), gradientShape, AsDeviceDescriptor(computationNodePtr->ValuePtr()->GetDeviceId())), [](ReferenceCount* ptr) { delete ptr; });
|
||||
auto mask = NDMaskPtr((nodeValue->Mask() != nullptr) ? new NDMask(nodeValue->Mask()->Shape(), nodeValue->Mask()->Device()) : nullptr, [](ReferenceCount* ptr) { delete ptr; });
|
||||
gradientValuePtr = ValuePtr(new Value(data, mask), [](ReferenceCount* ptr) { delete ptr; });
|
||||
|
||||
}
|
||||
gradientValuePtr->CopyFrom(*nodeValue);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LogicError("Unsupported DataType %s", DataTypeName(iter->first.GetDataType()));
|
||||
LogicError("Unsupported DataType %s", DataTypeName(gradientVarValuePair.first.GetDataType()));
|
||||
break;
|
||||
}
|
||||
|
||||
gradients[iter->first] = gradientValuePtr;
|
||||
gradients[gradientVarValuePair.first] = gradientValuePtr;
|
||||
}
|
||||
}
|
||||
|
||||
/*virtual*/ BackPropStatePtr CompositeFunction::Forward(const _Internal::_SimpleMap<Variable, const ValuePtr>& arguments,
|
||||
_Internal::_SimpleMap<Variable, ValuePtr>& outputs,
|
||||
const _Internal::_SimpleSet<Variable>& outputsToRetainBackwardStateFor,
|
||||
/*virtual*/ BackPropStatePtr CompositeFunction::Forward(const Internal::SimpleMap<Variable, const ValuePtr>& arguments,
|
||||
Internal::SimpleMap<Variable, ValuePtr>& outputs,
|
||||
const Internal::SimpleSet<Variable>& outputsToRetainBackwardStateFor,
|
||||
const DeviceDescriptor& computeDevice)
|
||||
{
|
||||
// TODO: How about zero argument functions?
|
||||
|
@ -752,24 +767,24 @@ namespace CNTK
|
|||
// Feed data into the arguments of the network
|
||||
PopulateNetworkInputs(arguments);
|
||||
|
||||
std::unordered_set<Variable> functionOutputs = _Internal::_SimpleVector<Variable>::CreateSimpleVector(this->Outputs()).GetAsUnorderedSet();
|
||||
std::unordered_set<Variable> functionOutputs = Internal::SimpleVector<Variable>(this->Outputs()).GetAsUnorderedSet();
|
||||
std::vector<ComputationNodeBasePtr> outputsToEvaluate;
|
||||
|
||||
for (auto iter = outputs.m_map->begin(); iter != outputs.m_map->end(); ++iter)
|
||||
for (auto outputVarValuePair : *outputs.m_map)
|
||||
{
|
||||
// Ensure that only a subset of this function's outputs are being asked to be evaluated
|
||||
if (functionOutputs.find(iter->first) == functionOutputs.end())
|
||||
if (functionOutputs.find(outputVarValuePair.first) == functionOutputs.end())
|
||||
InvalidArgument("Requested output is not an Ouptut of the Function");
|
||||
|
||||
auto outputComputationNode = m_variableToNodeMap[iter->first];
|
||||
auto outputComputationNode = m_variableToNodeMap[outputVarValuePair.first];
|
||||
outputsToEvaluate.push_back(outputComputationNode);
|
||||
}
|
||||
|
||||
// The 'outputsToRetainBackwardStateFor' nodes also need to be evaluated if not already specified in 'outputs'
|
||||
for (auto iter = outputsToRetainBackwardStateFor.m_set->begin(); iter != outputsToRetainBackwardStateFor.m_set->end(); ++iter)
|
||||
for (auto rootVarForBackprop : *outputsToRetainBackwardStateFor.m_set)
|
||||
{
|
||||
if (outputs.m_map->find(*iter) == outputs.m_map->end())
|
||||
outputsToEvaluate.push_back(m_variableToNodeMap[*iter]);
|
||||
if (outputs.m_map->find(rootVarForBackprop) == outputs.m_map->end())
|
||||
outputsToEvaluate.push_back(m_variableToNodeMap[rootVarForBackprop]);
|
||||
}
|
||||
|
||||
m_computationNetwork->ForwardProp(outputsToEvaluate);
|
||||
|
@ -778,12 +793,12 @@ namespace CNTK
|
|||
|
||||
// TODO: How to deal with the specified 'computeDevice'
|
||||
|
||||
return (outputsToRetainBackwardStateFor.Size() > 0) ? BackPropStatePtr(new CNTKBackPropState(this, { arguments.m_map->begin()->first, m_variableToNodeMap[arguments.m_map->begin()->first]->GetEvalTimeStamp() }), [](_ReferenceCounter* ptr) { delete ptr; }) : nullptr;
|
||||
return (outputsToRetainBackwardStateFor.Size() > 0) ? BackPropStatePtr(new CNTKBackPropState(this, { arguments.m_map->begin()->first, m_variableToNodeMap[arguments.m_map->begin()->first]->GetEvalTimeStamp() }), [](ReferenceCount* ptr) { delete ptr; }) : nullptr;
|
||||
}
|
||||
|
||||
/*virtual*/ void CompositeFunction::Backward(const BackPropStatePtr& state,
|
||||
const _Internal::_SimpleMap<Variable, const ValuePtr>& rootGradientValues,
|
||||
_Internal::_SimpleMap<Variable, ValuePtr>& backPropagatedGradientValuesForInputs)
|
||||
const Internal::SimpleMap<Variable, const ValuePtr>& rootGradientValues,
|
||||
Internal::SimpleMap<Variable, ValuePtr>& backPropagatedGradientValuesForInputs)
|
||||
{
|
||||
if ((state == nullptr) || (dynamic_cast<const CNTKBackPropState*>(state.GetPtr()) == nullptr))
|
||||
InvalidArgument("Invalid backprop state specified");
|
||||
|
@ -800,8 +815,8 @@ namespace CNTK
|
|||
// TODO: Avoid copying the data when possible
|
||||
|
||||
// Zero all gradients of nodes below the root nodes
|
||||
for (auto iter = rootGradientValues.m_map->begin(); iter != rootGradientValues.m_map->end(); ++iter)
|
||||
m_computationNetwork->ZeroInputGradients(m_variableToNodeMap[iter->first]);
|
||||
for (auto rootGradientVarValuePair : *rootGradientValues.m_map)
|
||||
m_computationNetwork->ZeroInputGradients(m_variableToNodeMap[rootGradientVarValuePair.first]);
|
||||
|
||||
// Feed data into the arguments of the network
|
||||
PopulateNetworkGradients(rootGradientValues);
|
||||
|
@ -815,19 +830,19 @@ namespace CNTK
|
|||
// TODO: How to deal with the specified 'computeDevice'
|
||||
}
|
||||
|
||||
/*virtual*/ void CompositeFunction::_ReplacePlaceholders(const _Internal::_SimpleMap<Placeholder, Variable>& placeholderReplacements, _Internal::_SimpleSet<const Function*>& visitedFunctions, _Internal::_SimpleSet<Placeholder>& replacedPlaceholders)
|
||||
/*virtual*/ void CompositeFunction::_ReplacePlaceholders(const Internal::SimpleMap<Placeholder, Variable>& placeholderReplacements, Internal::SimpleSet<const Function*>& visitedFunctions, Internal::SimpleSet<Placeholder>& replacedPlaceholders)
|
||||
{
|
||||
RootFunction()->_ReplacePlaceholders(placeholderReplacements, visitedFunctions, replacedPlaceholders);
|
||||
|
||||
// If any of the placeholders were replaced with Output variables, let's add the graph of function underneath each of those to 'm_allPrimitiveFunctions' set
|
||||
for (auto iter = replacedPlaceholders.m_set->begin(); iter != replacedPlaceholders.m_set->end(); ++iter)
|
||||
for (auto replacedPlaceholder : *replacedPlaceholders.m_set)
|
||||
{
|
||||
auto replacingVariable = placeholderReplacements[*iter];
|
||||
if (replacingVariable.Kind() == VariableKind::Output)
|
||||
auto replacingVariable = placeholderReplacements[replacedPlaceholder];
|
||||
if (replacingVariable.IsOutput())
|
||||
{
|
||||
auto ownerFunc = replacingVariable.Owner();
|
||||
_Internal::_SimpleSet<FunctionPtr> visitedFunctions;
|
||||
_DetermineInputs(ownerFunc, visitedFunctions);
|
||||
Internal::SimpleSet<FunctionPtr> visitedFunctions;
|
||||
DetermineInputs(ownerFunc, visitedFunctions);
|
||||
|
||||
// Add the newly visited functions to 'm_allPrimitiveFunctions' set
|
||||
m_allPrimitiveFunctions.m_set->insert(visitedFunctions.m_set->begin(), visitedFunctions.m_set->end());
|
||||
|
@ -855,22 +870,24 @@ namespace CNTK
|
|||
return CompositeFunction::Create(new PrimitiveFunction(PrimitiveOpType::Tanh, { operand }, Dictionary(), name), name);
|
||||
}
|
||||
|
||||
FunctionPtr _Combine(const _Internal::_SimpleVector<FunctionPtr>& operands, const std::wstring& name/* = L""*/)
|
||||
namespace Internal
|
||||
{
|
||||
_Internal::_SimpleSet<FunctionPtr> uniqueOperands;
|
||||
std::vector<Variable> inputs;
|
||||
for (size_t i = 0; i < operands.Size(); ++i)
|
||||
FunctionPtr Combine(const Internal::SimpleVector<FunctionPtr>& operands, const std::wstring& name/* = L""*/)
|
||||
{
|
||||
if (uniqueOperands.Contains(operands[i]))
|
||||
LogicError("All function operands specified to Combine must be unique");
|
||||
Internal::SimpleSet<FunctionPtr> uniqueOperands;
|
||||
std::vector<Variable> inputs;
|
||||
for (size_t i = 0; i < operands.Size(); ++i)
|
||||
{
|
||||
if (uniqueOperands.Contains(operands[i]))
|
||||
LogicError("All function operands specified to Combine must be unique");
|
||||
|
||||
uniqueOperands.Insert(operands[i]);
|
||||
auto currentFunctionOutputs = operands[i]->Outputs();
|
||||
std::copy(currentFunctionOutputs.begin(), currentFunctionOutputs.end(), std::back_inserter(inputs));
|
||||
uniqueOperands.Insert(operands[i]);
|
||||
auto currentFunctionOutputs = operands[i]->Outputs();
|
||||
std::copy(currentFunctionOutputs.begin(), currentFunctionOutputs.end(), std::back_inserter(inputs));
|
||||
}
|
||||
|
||||
return CompositeFunction::Create(new PrimitiveFunction(PrimitiveOpType::Combine, inputs, Dictionary(), name), name);
|
||||
}
|
||||
|
||||
return CompositeFunction::Create(new PrimitiveFunction(PrimitiveOpType::Combine, inputs, Dictionary(), name), name);
|
||||
|
||||
}
|
||||
|
||||
FunctionPtr CrossEntropyWithSoftmax(const Variable& output, const Variable& labels, const std::wstring& name/* = L""*/)
|
||||
|
@ -878,9 +895,9 @@ namespace CNTK
|
|||
return CompositeFunction::Create(new PrimitiveFunction(PrimitiveOpType::CrossEntropyWithSoftmax, { output, labels }, Dictionary(), name), name);
|
||||
}
|
||||
|
||||
FunctionPtr PredictionError(const Variable& prediction, const Variable& labels, const std::wstring& name/* = L""*/)
|
||||
FunctionPtr ClassificationError(const Variable& prediction, const Variable& labels, const std::wstring& name/* = L""*/)
|
||||
{
|
||||
return CompositeFunction::Create(new PrimitiveFunction(PrimitiveOpType::PredictionError, { prediction, labels }, Dictionary(), name), name);
|
||||
return CompositeFunction::Create(new PrimitiveFunction(PrimitiveOpType::ClassificationError, { prediction, labels }, Dictionary(), name), name);
|
||||
}
|
||||
|
||||
FunctionPtr Exp(const Variable& operand, const std::wstring& name/* = L""*/)
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "CNTKLibrary.h"
|
||||
#include <iterator>
|
||||
|
@ -19,7 +21,7 @@ namespace CNTK
|
|||
Tanh,
|
||||
Combine,
|
||||
CrossEntropyWithSoftmax,
|
||||
PredictionError,
|
||||
ClassificationError,
|
||||
Exp,
|
||||
PastValue,
|
||||
FutureValue,
|
||||
|
@ -29,6 +31,7 @@ namespace CNTK
|
|||
|
||||
inline const char* PrimitiveOpTypeName(PrimitiveOpType opType)
|
||||
{
|
||||
// TODO: Put these in table form
|
||||
if (opType == PrimitiveOpType::Plus)
|
||||
return "Plus";
|
||||
else if (opType == PrimitiveOpType::Times)
|
||||
|
@ -41,8 +44,8 @@ namespace CNTK
|
|||
return "Combine";
|
||||
else if (opType == PrimitiveOpType::CrossEntropyWithSoftmax)
|
||||
return "CrossEntropyWithSoftmax";
|
||||
else if (opType == PrimitiveOpType::PredictionError)
|
||||
return "PredictionError";
|
||||
else if (opType == PrimitiveOpType::ClassificationError)
|
||||
return "ClassificationError";
|
||||
else if (opType == PrimitiveOpType::Exp)
|
||||
return "Exp";
|
||||
else if (opType == PrimitiveOpType::PastValue)
|
||||
|
@ -65,17 +68,17 @@ namespace CNTK
|
|||
{
|
||||
}
|
||||
|
||||
virtual BackPropStatePtr Forward(const _Internal::_SimpleMap<Variable, const ValuePtr>& /*arguments*/,
|
||||
_Internal::_SimpleMap<Variable, ValuePtr>& /*outputs*/,
|
||||
const _Internal::_SimpleSet<Variable>& /*outputsToRetainBackwardStateFor*/,
|
||||
virtual BackPropStatePtr Forward(const Internal::SimpleMap<Variable, const ValuePtr>& /*arguments*/,
|
||||
Internal::SimpleMap<Variable, ValuePtr>& /*outputs*/,
|
||||
const Internal::SimpleSet<Variable>& /*outputsToRetainBackwardStateFor*/,
|
||||
const DeviceDescriptor& /*computeDevice*/) override
|
||||
{
|
||||
NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
virtual void Backward(const BackPropStatePtr& /*state*/,
|
||||
const _Internal::_SimpleMap<Variable, const ValuePtr>& /*rootGradientValues*/,
|
||||
_Internal::_SimpleMap<Variable, ValuePtr>& /*backPropagatedGradientValuesForInputs*/) override
|
||||
const Internal::SimpleMap<Variable, const ValuePtr>& /*rootGradientValues*/,
|
||||
Internal::SimpleMap<Variable, ValuePtr>& /*backPropagatedGradientValuesForInputs*/) override
|
||||
{
|
||||
NOT_IMPLEMENTED;
|
||||
}
|
||||
|
@ -91,6 +94,8 @@ namespace CNTK
|
|||
}
|
||||
|
||||
private:
|
||||
// The following helper functions are used to determine the output shape for different
|
||||
// types of primitive operations accounting for broadcasting and reductions where applicable.
|
||||
static NDShape UnaryElementwiseOpOutputShape(const NDShape& operandShape)
|
||||
{
|
||||
return operandShape;
|
||||
|
@ -98,17 +103,17 @@ namespace CNTK
|
|||
|
||||
static NDShape BinaryElementwiseOpOutputShape(PrimitiveOpType op, const NDShape& leftOperandShape, const NDShape& rightOperandShape, bool broadcastAllowed = true)
|
||||
{
|
||||
auto& shapeWithSmallerNumAxes = (leftOperandShape.NumAxes() > rightOperandShape.NumAxes()) ? rightOperandShape : leftOperandShape;
|
||||
auto& shapeWithLargerNumAxes = (leftOperandShape.NumAxes() > rightOperandShape.NumAxes()) ? leftOperandShape : rightOperandShape;
|
||||
const auto& shapeWithSmallerNumAxes = (leftOperandShape.NumAxes() > rightOperandShape.NumAxes()) ? rightOperandShape : leftOperandShape;
|
||||
const auto& shapeWithLargerNumAxes = (leftOperandShape.NumAxes() > rightOperandShape.NumAxes()) ? leftOperandShape : rightOperandShape;
|
||||
size_t numOutputAxes = shapeWithLargerNumAxes.NumAxes();
|
||||
std::vector<size_t> outputDims(numOutputAxes);
|
||||
for (size_t i = 0; i < shapeWithSmallerNumAxes.NumAxes(); ++i)
|
||||
{
|
||||
if ((leftOperandShape[i] == NDShape::InferredDimension) && (rightOperandShape[i] == NDShape::InferredDimension))
|
||||
outputDims[i] = NDShape::InferredDimension;
|
||||
else if ((leftOperandShape[i] == NDShape::InferredDimension) && (rightOperandShape[i] != NDShape::InferredDimension))
|
||||
else if (leftOperandShape[i] == NDShape::InferredDimension)
|
||||
outputDims[i] = rightOperandShape[i];
|
||||
else if ((leftOperandShape[i] != NDShape::InferredDimension) && (rightOperandShape[i] == NDShape::InferredDimension))
|
||||
else if (rightOperandShape[i] == NDShape::InferredDimension)
|
||||
outputDims[i] = leftOperandShape[i];
|
||||
else
|
||||
{
|
||||
|
@ -126,7 +131,7 @@ namespace CNTK
|
|||
return NDShape(std::move(outputDims));
|
||||
}
|
||||
|
||||
static NDShape TimesOpOutputShape(const NDShape& leftOperandShape, const NDShape& rightOperandShape, bool broadcastAllowed = true)
|
||||
static NDShape TimesOpOutputShape(const NDShape& leftOperandShape, const NDShape& rightOperandShape)
|
||||
{
|
||||
if (rightOperandShape.NumAxes() > 2)
|
||||
RuntimeError("The right operand of a times operation can have at most 2 axes");
|
||||
|
@ -166,6 +171,7 @@ namespace CNTK
|
|||
return NDShape(std::move(outputDims));
|
||||
}
|
||||
|
||||
// TODO: Reconcile this with the ComputationNode::Validate functionality in core CNTK to avoid duplication of inference logic
|
||||
static std::vector<Variable> GetOutputVariables(PrimitiveOpType op, const std::vector<Variable>& inputs, Function* owner)
|
||||
{
|
||||
std::vector<Variable> outputs;
|
||||
|
@ -175,9 +181,9 @@ namespace CNTK
|
|||
|
||||
// We currently require that the inputs' dynamic axes if any match
|
||||
std::vector<Axis> outputDynamicAxes = inputs[0].DynamicAxes();
|
||||
for (size_t i = 1; i < inputs.size(); ++i)
|
||||
for (auto inputVar : inputs)
|
||||
{
|
||||
auto currentInputDynamicAxes = inputs[i].DynamicAxes();
|
||||
auto currentInputDynamicAxes = inputVar.DynamicAxes();
|
||||
if (outputDynamicAxes.empty())
|
||||
outputDynamicAxes = currentInputDynamicAxes;
|
||||
else
|
||||
|
@ -210,7 +216,7 @@ namespace CNTK
|
|||
outputs.push_back(Variable(TimesOpOutputShape(inputs[0].Shape(), inputs[1].Shape()), outputDataType, owner, outputDynamicAxes));
|
||||
break;
|
||||
case PrimitiveOpType::CrossEntropyWithSoftmax:
|
||||
case PrimitiveOpType::PredictionError:
|
||||
case PrimitiveOpType::ClassificationError:
|
||||
{
|
||||
assert(inputs.size() == 2);
|
||||
|
||||
|
@ -274,10 +280,10 @@ namespace CNTK
|
|||
private:
|
||||
std::pair<Variable, int64_t> m_evalTimeStamp;
|
||||
};
|
||||
typedef _Internal::_ReferenceCounterSharedPtr<CNTKBackPropState> CNTKBackPropStatePtr;
|
||||
typedef Internal::ReferenceCountedPtr<CNTKBackPropState> CNTKBackPropStatePtr;
|
||||
|
||||
class CompositeFunction;
|
||||
typedef _Internal::_ReferenceCounterSharedPtr<CompositeFunction> CompositeFunctionPtr;
|
||||
typedef Internal::ReferenceCountedPtr<CompositeFunction> CompositeFunctionPtr;
|
||||
|
||||
class CompositeFunction final : public Function
|
||||
{
|
||||
|
@ -286,53 +292,53 @@ namespace CNTK
|
|||
public:
|
||||
static CompositeFunctionPtr Create(const FunctionPtr& rootFunction, const std::wstring& name = L"")
|
||||
{
|
||||
_Internal::_SimpleSet<FunctionPtr> visitedFunctions;
|
||||
Internal::SimpleSet<FunctionPtr> visitedFunctions;
|
||||
|
||||
// Call _DetermineInputs to get the set of all functions in the graph
|
||||
_DetermineInputs(rootFunction, visitedFunctions);
|
||||
// Call DetermineInputs to get the set of all functions in the graph
|
||||
DetermineInputs(rootFunction, visitedFunctions);
|
||||
|
||||
auto func = new CompositeFunction(rootFunction, std::move(visitedFunctions), name);
|
||||
return CompositeFunctionPtr(func, [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
return CompositeFunctionPtr(func, [](ReferenceCount* ptr) { delete ptr; });
|
||||
}
|
||||
|
||||
virtual BackPropStatePtr Forward(const _Internal::_SimpleMap<Variable, const ValuePtr>& arguments,
|
||||
_Internal::_SimpleMap<Variable, ValuePtr>& outputs,
|
||||
const _Internal::_SimpleSet<Variable>& outputsToRetainBackwardStateFor,
|
||||
virtual BackPropStatePtr Forward(const Internal::SimpleMap<Variable, const ValuePtr>& arguments,
|
||||
Internal::SimpleMap<Variable, ValuePtr>& outputs,
|
||||
const Internal::SimpleSet<Variable>& outputsToRetainBackwardStateFor,
|
||||
const DeviceDescriptor& computeDevice) override;
|
||||
|
||||
virtual void Backward(const BackPropStatePtr& state,
|
||||
const _Internal::_SimpleMap<Variable, const ValuePtr>& rootGradientValues,
|
||||
_Internal::_SimpleMap<Variable, ValuePtr>& backPropagatedGradientValuesForInputs) override;
|
||||
const Internal::SimpleMap<Variable, const ValuePtr>& rootGradientValues,
|
||||
Internal::SimpleMap<Variable, ValuePtr>& backPropagatedGradientValuesForInputs) override;
|
||||
|
||||
private:
|
||||
virtual void _ReplacePlaceholders(const _Internal::_SimpleMap<Placeholder, Variable>& placeholderReplacements, _Internal::_SimpleSet<const Function*>& visitedFunctions, _Internal::_SimpleSet<Placeholder>& replacedPlaceholders) override;
|
||||
virtual void _ReplacePlaceholders(const Internal::SimpleMap<Placeholder, Variable>& placeholderReplacements, Internal::SimpleSet<const Function*>& visitedFunctions, Internal::SimpleSet<Placeholder>& replacedPlaceholders) override;
|
||||
|
||||
CompositeFunction(const FunctionPtr& rootFunction, _Internal::_SimpleSet<FunctionPtr>&& allPrimitiveFunctions, const std::wstring& name)
|
||||
CompositeFunction(const FunctionPtr& rootFunction, Internal::SimpleSet<FunctionPtr>&& allPrimitiveFunctions, const std::wstring& name)
|
||||
: Function({}, rootFunction->Outputs(), rootFunction, name), m_allPrimitiveFunctions(std::move(allPrimitiveFunctions))
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<Variable> DetermineInputs() const
|
||||
{
|
||||
_Internal::_SimpleSet<FunctionPtr> visitedFunctions;
|
||||
return _DetermineInputs(RootFunction(), visitedFunctions);
|
||||
Internal::SimpleSet<FunctionPtr> visitedFunctions;
|
||||
return DetermineInputs(RootFunction(), visitedFunctions);
|
||||
}
|
||||
|
||||
static std::vector<Variable> _DetermineInputs(const FunctionPtr& rootFunction, _Internal::_SimpleSet<FunctionPtr>& visitedFunctions)
|
||||
// Recursively traverses the Function graph underlying the 'rootFunction' to determine all the leaves (aka inputs) of the graph
|
||||
static std::vector<Variable> DetermineInputs(const FunctionPtr& rootFunction, Internal::SimpleSet<FunctionPtr>& visitedFunctions)
|
||||
{
|
||||
visitedFunctions.Insert(rootFunction);
|
||||
|
||||
std::vector<Variable> inputs;
|
||||
std::vector<Variable> rootFunctionInputs = rootFunction->Inputs();
|
||||
for (size_t i = 0; i < rootFunctionInputs.size(); ++i)
|
||||
for (auto rootInput : rootFunctionInputs)
|
||||
{
|
||||
Variable currentInput = rootFunctionInputs[i];
|
||||
if (currentInput.Kind() != VariableKind::Output)
|
||||
inputs.push_back(currentInput);
|
||||
else if (!visitedFunctions.Contains(currentInput.Owner()))
|
||||
if (!rootInput.IsOutput())
|
||||
inputs.push_back(rootInput);
|
||||
else if (!visitedFunctions.Contains(rootInput.Owner()))
|
||||
{
|
||||
FunctionPtr function = currentInput.Owner();
|
||||
std::vector<Variable> functionInputs = _DetermineInputs(function, visitedFunctions);
|
||||
FunctionPtr function = rootInput.Owner();
|
||||
std::vector<Variable> functionInputs = DetermineInputs(function, visitedFunctions);
|
||||
std::copy(functionInputs.begin(), functionInputs.end(), std::back_inserter(inputs));
|
||||
}
|
||||
}
|
||||
|
@ -341,7 +347,7 @@ namespace CNTK
|
|||
}
|
||||
|
||||
template <typename ElementType>
|
||||
Microsoft::MSR::CNTK::ComputationNetworkPtr GetComputationNetwork(const DeviceDescriptor& device, const _Internal::_SimpleSet<Variable>& backpropRoots);
|
||||
Microsoft::MSR::CNTK::ComputationNetworkPtr GetComputationNetwork(const DeviceDescriptor& device, const Internal::SimpleSet<Variable>& backpropRoots);
|
||||
|
||||
template <typename ElementType>
|
||||
static Microsoft::MSR::CNTK::ComputationNodeBasePtr GetOutputVariableNode(const Variable& variable, Microsoft::MSR::CNTK::ComputationNetworkPtr& network, Microsoft::MSR::CNTK::ComputationNetworkBuilder<ElementType>& builder, std::unordered_map<Variable, Microsoft::MSR::CNTK::ComputationNodeBasePtr>& variableToNodeMap, std::unordered_map<Variable, bool>& isVariableRootMap);
|
||||
|
@ -349,8 +355,8 @@ namespace CNTK
|
|||
template <typename ElementType>
|
||||
static Microsoft::MSR::CNTK::ComputationNodeBasePtr GetNode(const Variable& variable, Microsoft::MSR::CNTK::ComputationNetworkPtr& network, Microsoft::MSR::CNTK::ComputationNetworkBuilder<ElementType>& builder, std::unordered_map<Variable, Microsoft::MSR::CNTK::ComputationNodeBasePtr>& variableToNodeMap, std::unordered_map<Variable, bool>& isVariableRootMap);
|
||||
|
||||
void PopulateNetworkInputs(const _Internal::_SimpleMap<Variable, const ValuePtr>& arguments);
|
||||
void PopulateNetworkGradients(const _Internal::_SimpleMap<Variable, const ValuePtr>& gradients);
|
||||
void PopulateNetworkInputs(const Internal::SimpleMap<Variable, const ValuePtr>& arguments);
|
||||
void PopulateNetworkGradients(const Internal::SimpleMap<Variable, const ValuePtr>& gradients);
|
||||
|
||||
void GetNetworkOutputs(std::unordered_map<Variable, ValuePtr>& outputs);
|
||||
void GetNetworkGradients(std::unordered_map<Variable, ValuePtr>& gradients);
|
||||
|
@ -362,10 +368,23 @@ namespace CNTK
|
|||
static ValuePtr GetValueObjectFromCNTKImplMatrixAndMBLayout(Variable var, const Microsoft::MSR::CNTK::Matrix<ElementType>& matrix, const Microsoft::MSR::CNTK::MBLayoutPtr& layout);
|
||||
|
||||
private:
|
||||
_Internal::_SimpleSet<FunctionPtr> m_allPrimitiveFunctions;
|
||||
|
||||
// Set of all primitive functions in the graph underlying 'this' Function. Also keeps the primitive Function objects alive
|
||||
// by holding strong references to them
|
||||
Internal::SimpleSet<FunctionPtr> m_allPrimitiveFunctions;
|
||||
|
||||
// A map from Variable objects to ComputationNode objects in the ComputationNetwork instance that implements 'this' Composite Function
|
||||
std::unordered_map<Variable, Microsoft::MSR::CNTK::ComputationNodeBasePtr> m_variableToNodeMap;
|
||||
|
||||
// A map that tells whether a Variable in the graph underlying 'this' Function is a root of the graph
|
||||
std::unordered_map<Variable, bool> m_isVariableRootMap;
|
||||
|
||||
Microsoft::MSR::CNTK::ComputationNetworkPtr m_computationNetwork;
|
||||
|
||||
// The backpropRoots sepecified in the most recent 'Forward' call on 'this' Function.
|
||||
// This indicates for which of it's roots has 'this' Function retained required intermediate
|
||||
// states from the previos Forward call to be able to backpropagate gradients backwards from in
|
||||
// the next 'Backward' call.
|
||||
std::unordered_set<Variable> m_currentBackpropRoots;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -17,9 +17,9 @@ namespace CNTK
|
|||
{
|
||||
template <typename ElementType>
|
||||
static TensorView<ElementType>* AllocateTensorView(const NDShape& viewShape,
|
||||
const DeviceDescriptor& device,
|
||||
void* dataBuffer,
|
||||
size_t bufferSizeInBytes)
|
||||
const DeviceDescriptor& device,
|
||||
void* dataBuffer,
|
||||
size_t bufferSizeInBytes)
|
||||
{
|
||||
if (dataBuffer == nullptr)
|
||||
InvalidArgument("Cannot create a NDArrayView over a null data buffer");
|
||||
|
@ -33,10 +33,10 @@ namespace CNTK
|
|||
}
|
||||
|
||||
static void* AllocateTensorView(CNTK::DataType dataType,
|
||||
const NDShape& viewShape,
|
||||
const DeviceDescriptor& device,
|
||||
void* dataBuffer,
|
||||
size_t bufferSizeInBytes)
|
||||
const NDShape& viewShape,
|
||||
const DeviceDescriptor& device,
|
||||
void* dataBuffer,
|
||||
size_t bufferSizeInBytes)
|
||||
{
|
||||
switch (dataType)
|
||||
{
|
||||
|
@ -195,7 +195,7 @@ namespace CNTK
|
|||
const TensorView<ElementType>* NDArrayView::GetTensorView() const
|
||||
{
|
||||
if (AsDataType<ElementType>() != m_dataType)
|
||||
LogicError("NDArrayView::GetWritableTensorView: The specified ElementType %s does not match the DataType %s", typeid(ElementType).name(), DataTypeName(m_dataType));
|
||||
LogicError("NDArrayView::GetTensorView: The specified ElementType %s does not match the DataType %s", typeid(ElementType).name(), DataTypeName(m_dataType));
|
||||
|
||||
return (const TensorView<ElementType>*)(m_tensorView);
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ namespace CNTK
|
|||
|
||||
NDArrayViewPtr NDArrayView::DeepClone(bool readOnly/* = false*/) const
|
||||
{
|
||||
NDArrayViewPtr newView(new NDArrayView(this->GetDataType(), this->GetStorageFormat(), this->Shape(), this->Device()), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
NDArrayViewPtr newView(new NDArrayView(this->GetDataType(), this->GetStorageFormat(), this->Shape(), this->Device()), [](ReferenceCount* ptr) { delete ptr; });
|
||||
switch (m_dataType)
|
||||
{
|
||||
case DataType::Float:
|
||||
|
@ -234,7 +234,7 @@ namespace CNTK
|
|||
}
|
||||
|
||||
newView->m_isReadOnly = readOnly;
|
||||
return NDArrayViewPtr(newView, [](_ReferenceCounter* ptr) {
|
||||
return NDArrayViewPtr(newView, [](ReferenceCount* ptr) {
|
||||
delete ptr;
|
||||
});
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ namespace CNTK
|
|||
}
|
||||
|
||||
auto aliasView = new NDArrayView(GetDataType(), Device(), GetStorageFormat(), Shape(), IsReadOnly() || readOnly, tensorView);;
|
||||
return NDArrayViewPtr(aliasView, [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
return NDArrayViewPtr(aliasView, [](ReferenceCount* ptr) { delete ptr; });
|
||||
}
|
||||
|
||||
// TODO: This could actually be strided?
|
||||
|
@ -316,19 +316,19 @@ namespace CNTK
|
|||
}
|
||||
|
||||
template <typename ElementType>
|
||||
NDArrayViewPtr NDArrayView::RandomUniform(const NDShape& shape, double rangeStart, double rangeEnd, unsigned long seed, const DeviceDescriptor& device/* = DeviceDescriptor::DefaultDevice()*/)
|
||||
NDArrayViewPtr NDArrayView::RandomUniform(const NDShape& shape, double rangeBegin, double rangeEnd, unsigned long seed, const DeviceDescriptor& device/* = DeviceDescriptor::DefaultDevice()*/)
|
||||
{
|
||||
auto matrixDims = GetMatrixDimensions(shape);
|
||||
auto randomUniformMatrix = std::make_shared<Matrix<ElementType>>(Matrix<ElementType>::RandomUniform(matrixDims.first, matrixDims.second, AsCNTKImplDeviceId(device), (ElementType)rangeStart, (ElementType)rangeEnd, seed));
|
||||
auto randomUniformMatrix = std::make_shared<Matrix<ElementType>>(Matrix<ElementType>::RandomUniform(matrixDims.first, matrixDims.second, AsCNTKImplDeviceId(device), (ElementType)rangeBegin, (ElementType)rangeEnd, seed));
|
||||
auto tensorView = new TensorView<ElementType>(randomUniformMatrix, AsTensorShape(shape));
|
||||
|
||||
auto view = new NDArrayView(AsDataType<ElementType>(), device, StorageFormat::Dense, shape, false, tensorView);
|
||||
return NDArrayViewPtr(view, [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
return NDArrayViewPtr(view, [](ReferenceCount* ptr) { delete ptr; });
|
||||
}
|
||||
|
||||
// Explicit template instantiations
|
||||
template CNTK_API NDArrayViewPtr NDArrayView::RandomUniform<float>(const NDShape& shape, double rangeStart, double rangeEnd, unsigned long seed, const DeviceDescriptor& device/* = DeviceDescriptor::DefaultDevice()*/);
|
||||
template CNTK_API NDArrayViewPtr NDArrayView::RandomUniform<double>(const NDShape& shape, double rangeStart, double rangeEnd, unsigned long seed, const DeviceDescriptor& device/* = DeviceDescriptor::DefaultDevice()*/);
|
||||
template CNTK_API NDArrayViewPtr NDArrayView::RandomUniform<float>(const NDShape& shape, double rangeBegin, double rangeEnd, unsigned long seed, const DeviceDescriptor& device/* = DeviceDescriptor::DefaultDevice()*/);
|
||||
template CNTK_API NDArrayViewPtr NDArrayView::RandomUniform<double>(const NDShape& shape, double rangeBegin, double rangeEnd, unsigned long seed, const DeviceDescriptor& device/* = DeviceDescriptor::DefaultDevice()*/);
|
||||
|
||||
template CNTK_API const float* NDArrayView::DataBuffer<float>() const;
|
||||
template CNTK_API const double* NDArrayView::DataBuffer<double>() const;
|
||||
|
|
|
@ -99,11 +99,11 @@ namespace CNTK
|
|||
NDMaskPtr newMask = new NDMask(this->Shape(), this->Device());
|
||||
newMask->CopyFrom(*this);
|
||||
|
||||
return NDMaskPtr(newMask, [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
return NDMaskPtr(newMask, [](ReferenceCount* ptr) { delete ptr; });
|
||||
}
|
||||
|
||||
NDMaskPtr NDMask::Alias() const
|
||||
{
|
||||
return NDMaskPtr(new NDMask(this->Shape(), new Matrix<char>(GetMatrix()->AsReference())), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
return NDMaskPtr(new NDMask(this->Shape(), new Matrix<char>(GetMatrix()->AsReference())), [](ReferenceCount* ptr) { delete ptr; });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,36 +9,61 @@
|
|||
|
||||
namespace CNTK
|
||||
{
|
||||
namespace _Internal
|
||||
namespace Internal
|
||||
{
|
||||
#pragma region _SimpleVector
|
||||
ReferenceCount::ReferenceCount()
|
||||
: m_rc(new std::atomic<size_t>(0))
|
||||
{}
|
||||
|
||||
/*virtual*/ ReferenceCount::~ReferenceCount()
|
||||
{
|
||||
delete m_rc;
|
||||
}
|
||||
|
||||
size_t ReferenceCount::AddReference()
|
||||
{
|
||||
return ++(*m_rc);
|
||||
}
|
||||
|
||||
size_t ReferenceCount::RemoveReference()
|
||||
{
|
||||
assert(m_rc->load() > 0);
|
||||
return --(*m_rc);
|
||||
}
|
||||
|
||||
size_t ReferenceCount::GetReferenceCount()
|
||||
{
|
||||
return m_rc->load();
|
||||
}
|
||||
|
||||
#pragma region SimpleVector
|
||||
|
||||
template <typename T>
|
||||
_SimpleVector<T>::_SimpleVector()
|
||||
SimpleVector<T>::SimpleVector()
|
||||
: m_vector(new std::vector<T>())
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
_SimpleVector<T>::_SimpleVector(size_t numElements, const T& initVal/* = T()*/)
|
||||
SimpleVector<T>::SimpleVector(size_t numElements, const T& initVal/* = T()*/)
|
||||
: m_vector(new std::vector<T>(numElements, initVal))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
_SimpleVector<T>::~_SimpleVector()
|
||||
SimpleVector<T>::~SimpleVector()
|
||||
{
|
||||
delete m_vector;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
_SimpleVector<T>::_SimpleVector(const _SimpleVector<T>& other)
|
||||
SimpleVector<T>::SimpleVector(const SimpleVector<T>& other)
|
||||
: m_vector(new std::vector<T>(*other.m_vector))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
_SimpleVector<T>& _SimpleVector<T>::operator=(const _SimpleVector<T>& other)
|
||||
SimpleVector<T>& SimpleVector<T>::operator=(const SimpleVector<T>& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
|
@ -50,14 +75,14 @@ namespace CNTK
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
_SimpleVector<T>::_SimpleVector(_SimpleVector<T>&& other)
|
||||
SimpleVector<T>::SimpleVector(SimpleVector<T>&& other)
|
||||
: m_vector(nullptr)
|
||||
{
|
||||
*this = std::move(other);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
_SimpleVector<T>& _SimpleVector<T>::operator=(_SimpleVector<T>&& other)
|
||||
SimpleVector<T>& SimpleVector<T>::operator=(SimpleVector<T>&& other)
|
||||
{
|
||||
assert(this != &other);
|
||||
|
||||
|
@ -70,88 +95,88 @@ namespace CNTK
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
T& _SimpleVector<T>::operator[](size_t idx)
|
||||
T& SimpleVector<T>::operator[](size_t idx)
|
||||
{
|
||||
assert(idx < Size());
|
||||
return (*m_vector)[idx];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& _SimpleVector<T>::operator[](size_t idx) const
|
||||
const T& SimpleVector<T>::operator[](size_t idx) const
|
||||
{
|
||||
assert(idx < Size());
|
||||
return (*m_vector)[idx];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t _SimpleVector<T>::Size() const
|
||||
size_t SimpleVector<T>::Size() const
|
||||
{
|
||||
return m_vector->size();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* _SimpleVector<T>::Data()
|
||||
T* SimpleVector<T>::Data()
|
||||
{
|
||||
return m_vector->data();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T* _SimpleVector<T>::Data() const
|
||||
const T* SimpleVector<T>::Data() const
|
||||
{
|
||||
return m_vector->data();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void _SimpleVector<T>::PushBack(const T& value)
|
||||
void SimpleVector<T>::PushBack(const T& value)
|
||||
{
|
||||
m_vector->push_back(value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void _SimpleVector<T>::PushBack(T&& value)
|
||||
void SimpleVector<T>::PushBack(T&& value)
|
||||
{
|
||||
m_vector->push_back(std::move(value));
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
bool operator==(const _SimpleVector<ValueType>& first, const _SimpleVector<ValueType>& second)
|
||||
bool operator==(const SimpleVector<ValueType>& first, const SimpleVector<ValueType>& second)
|
||||
{
|
||||
return *first.m_vector == *second.m_vector;
|
||||
}
|
||||
|
||||
// Explicit template instantiations
|
||||
template class _SimpleVector<Variable>;
|
||||
template class _SimpleVector<size_t>;
|
||||
template class _SimpleVector<Axis>;
|
||||
template class _SimpleVector<FunctionPtr>;
|
||||
template class SimpleVector<Variable>;
|
||||
template class SimpleVector<size_t>;
|
||||
template class SimpleVector<Axis>;
|
||||
template class SimpleVector<FunctionPtr>;
|
||||
|
||||
template bool operator==(const _SimpleVector<size_t>& first, const _SimpleVector<size_t>& second);
|
||||
template bool operator==(const SimpleVector<size_t>& first, const SimpleVector<size_t>& second);
|
||||
|
||||
#pragma endregion _SimpleVector
|
||||
#pragma endregion SimpleVector
|
||||
|
||||
#pragma region _SimpleSet
|
||||
#pragma region SimpleSet
|
||||
|
||||
template <typename KeyType>
|
||||
_SimpleSet<KeyType>::_SimpleSet()
|
||||
SimpleSet<KeyType>::SimpleSet()
|
||||
: m_set(new std::unordered_set<KeyType>())
|
||||
{
|
||||
}
|
||||
|
||||
template <typename KeyType>
|
||||
_SimpleSet<KeyType>::~_SimpleSet()
|
||||
SimpleSet<KeyType>::~SimpleSet()
|
||||
{
|
||||
delete m_set;
|
||||
}
|
||||
|
||||
template <typename KeyType>
|
||||
_SimpleSet<KeyType>::_SimpleSet(const _SimpleSet& other)
|
||||
SimpleSet<KeyType>::SimpleSet(const SimpleSet& other)
|
||||
: m_set(nullptr)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
template <typename KeyType>
|
||||
_SimpleSet<KeyType>& _SimpleSet<KeyType>::operator=(const _SimpleSet& other)
|
||||
SimpleSet<KeyType>& SimpleSet<KeyType>::operator=(const SimpleSet& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
|
@ -163,14 +188,14 @@ namespace CNTK
|
|||
}
|
||||
|
||||
template <typename KeyType>
|
||||
_SimpleSet<KeyType>::_SimpleSet(_SimpleSet&& other)
|
||||
SimpleSet<KeyType>::SimpleSet(SimpleSet&& other)
|
||||
: m_set(nullptr)
|
||||
{
|
||||
*this = std::move(other);
|
||||
}
|
||||
|
||||
template <typename KeyType>
|
||||
_SimpleSet<KeyType>& _SimpleSet<KeyType>::operator=(_SimpleSet&& other)
|
||||
SimpleSet<KeyType>& SimpleSet<KeyType>::operator=(SimpleSet&& other)
|
||||
{
|
||||
assert(this != &other);
|
||||
|
||||
|
@ -182,73 +207,73 @@ namespace CNTK
|
|||
}
|
||||
|
||||
template <typename KeyType>
|
||||
bool _SimpleSet<KeyType>::Insert(const KeyType& key)
|
||||
bool SimpleSet<KeyType>::Insert(const KeyType& key)
|
||||
{
|
||||
return m_set->insert(key).second;
|
||||
}
|
||||
|
||||
template <typename KeyType>
|
||||
bool _SimpleSet<KeyType>::Contains(const KeyType& key) const
|
||||
bool SimpleSet<KeyType>::Contains(const KeyType& key) const
|
||||
{
|
||||
return (m_set->find(key) != m_set->end());
|
||||
}
|
||||
|
||||
template <typename KeyType>
|
||||
size_t _SimpleSet<KeyType>::Size() const
|
||||
size_t SimpleSet<KeyType>::Size() const
|
||||
{
|
||||
return m_set->size();
|
||||
}
|
||||
|
||||
template <typename KeyType>
|
||||
_SimpleSet<KeyType>::operator _SimpleVector<KeyType>() const
|
||||
SimpleSet<KeyType>::operator SimpleVector<KeyType>() const
|
||||
{
|
||||
_SimpleVector<KeyType> retVector;
|
||||
for (auto iter = m_set->begin(); iter != m_set->end(); ++iter)
|
||||
retVector.PushBack(*iter);
|
||||
SimpleVector<KeyType> retVector;
|
||||
for (auto key : *m_set)
|
||||
retVector.PushBack(key);
|
||||
|
||||
return retVector;
|
||||
}
|
||||
|
||||
template <typename KeyType>
|
||||
bool operator==(const _SimpleSet<KeyType>& first, const _SimpleSet<KeyType>& second)
|
||||
bool operator==(const SimpleSet<KeyType>& first, const SimpleSet<KeyType>& second)
|
||||
{
|
||||
return *first.m_set == *second.m_set;
|
||||
}
|
||||
|
||||
// Explicit template instantiations
|
||||
template class _SimpleSet<FunctionPtr>;
|
||||
template class _SimpleSet<Variable>;
|
||||
template class _SimpleSet<Placeholder>;
|
||||
template class _SimpleSet<const Function*>;
|
||||
template class SimpleSet<FunctionPtr>;
|
||||
template class SimpleSet<Variable>;
|
||||
template class SimpleSet<Placeholder>;
|
||||
template class SimpleSet<const Function*>;
|
||||
|
||||
template bool operator==(const _SimpleSet<Variable>& first, const _SimpleSet<Variable>& second);
|
||||
template bool operator==(const _SimpleSet<Placeholder>& first, const _SimpleSet<Placeholder>& second);
|
||||
template bool operator==(const SimpleSet<Variable>& first, const SimpleSet<Variable>& second);
|
||||
template bool operator==(const SimpleSet<Placeholder>& first, const SimpleSet<Placeholder>& second);
|
||||
|
||||
#pragma endregion _SimpleSet
|
||||
#pragma endregion SimpleSet
|
||||
|
||||
#pragma region _SimpleMap
|
||||
#pragma region SimpleMap
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
_SimpleMap<KeyType, ValueType>::_SimpleMap()
|
||||
SimpleMap<KeyType, ValueType>::SimpleMap()
|
||||
: m_map(new std::unordered_map<KeyType, ValueType>())
|
||||
{
|
||||
}
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
_SimpleMap<KeyType, ValueType>::~_SimpleMap()
|
||||
SimpleMap<KeyType, ValueType>::~SimpleMap()
|
||||
{
|
||||
delete m_map;
|
||||
}
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
_SimpleMap<KeyType, ValueType>::_SimpleMap(const _SimpleMap& other)
|
||||
SimpleMap<KeyType, ValueType>::SimpleMap(const SimpleMap& other)
|
||||
: m_map(nullptr)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
_SimpleMap<KeyType, ValueType>& _SimpleMap<KeyType, ValueType>::operator=(const _SimpleMap& other)
|
||||
SimpleMap<KeyType, ValueType>& SimpleMap<KeyType, ValueType>::operator=(const SimpleMap& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
|
@ -260,14 +285,14 @@ namespace CNTK
|
|||
}
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
_SimpleMap<KeyType, ValueType>::_SimpleMap(_SimpleMap&& other)
|
||||
SimpleMap<KeyType, ValueType>::SimpleMap(SimpleMap&& other)
|
||||
: m_map(nullptr)
|
||||
{
|
||||
*this = std::move(other);
|
||||
}
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
_SimpleMap<KeyType, ValueType>& _SimpleMap<KeyType, ValueType>::operator=(_SimpleMap&& other)
|
||||
SimpleMap<KeyType, ValueType>& SimpleMap<KeyType, ValueType>::operator=(SimpleMap&& other)
|
||||
{
|
||||
assert(this != &other);
|
||||
|
||||
|
@ -279,51 +304,51 @@ namespace CNTK
|
|||
}
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
ValueType& _SimpleMap<KeyType, ValueType>::operator[](const KeyType& key)
|
||||
ValueType& SimpleMap<KeyType, ValueType>::operator[](const KeyType& key)
|
||||
{
|
||||
return (*m_map)[key];
|
||||
}
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
const ValueType& _SimpleMap<KeyType, ValueType>::operator[](const KeyType& key) const
|
||||
const ValueType& SimpleMap<KeyType, ValueType>::operator[](const KeyType& key) const
|
||||
{
|
||||
return (*m_map)[key];
|
||||
}
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
bool _SimpleMap<KeyType, ValueType>::Insert(const KeyType& key, const ValueType& value)
|
||||
bool SimpleMap<KeyType, ValueType>::Insert(const KeyType& key, const ValueType& value)
|
||||
{
|
||||
return m_map->insert({ key, value }).second;
|
||||
}
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
bool _SimpleMap<KeyType, ValueType>::Contains(const KeyType& key) const
|
||||
bool SimpleMap<KeyType, ValueType>::Contains(const KeyType& key) const
|
||||
{
|
||||
return (m_map->find(key) != m_map->end());
|
||||
}
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
size_t _SimpleMap<KeyType, ValueType>::Size() const
|
||||
size_t SimpleMap<KeyType, ValueType>::Size() const
|
||||
{
|
||||
return m_map->size();
|
||||
}
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
_SimpleSet<KeyType> _SimpleMap<KeyType, ValueType>::Keys() const
|
||||
SimpleSet<KeyType> SimpleMap<KeyType, ValueType>::Keys() const
|
||||
{
|
||||
_SimpleSet<KeyType> keys;
|
||||
for (auto iter = m_map->begin(); iter != m_map->end(); ++iter)
|
||||
keys.Insert(iter->first);
|
||||
SimpleSet<KeyType> keys;
|
||||
for (auto keyValuePair : *m_map)
|
||||
keys.Insert(keyValuePair.first);
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
// Explicit template instantiations
|
||||
template class _SimpleMap<Variable, ValuePtr>;
|
||||
template class _SimpleMap<Variable, const ValuePtr>;
|
||||
template class _SimpleMap<Placeholder, Variable>;
|
||||
template class SimpleMap<Variable, ValuePtr>;
|
||||
template class SimpleMap<Variable, const ValuePtr>;
|
||||
template class SimpleMap<Placeholder, Variable>;
|
||||
|
||||
#pragma endregion _SimpleMap
|
||||
#pragma endregion SimpleMap
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ namespace CNTK
|
|||
: m_valueType(GetValueType<T>())
|
||||
{
|
||||
static_assert(std::is_same<T, NDShape>::value ||
|
||||
std::is_same<T, _Internal::_SimpleVector<DictionaryValue>>::value,
|
||||
std::is_same<T, Internal::SimpleVector<DictionaryValue>>::value,
|
||||
"Unsupported ValueType");
|
||||
|
||||
AllocateDataPtr(value);
|
||||
|
@ -84,6 +84,8 @@ namespace CNTK
|
|||
DictionaryValue(const DictionaryValue& other)
|
||||
: m_valueType(Type::Bool)
|
||||
{
|
||||
// The m_valueType must hvae been set to a non-ptr type to prevent an attempt to interpret
|
||||
// the underlying underlying uninitialized value as a ptr and free it.
|
||||
*this = other;
|
||||
}
|
||||
|
||||
|
@ -99,7 +101,7 @@ namespace CNTK
|
|||
if (other.m_valueType == Type::NDShape)
|
||||
AllocateDataPtr(other.GetValue<NDShape>());
|
||||
else if (other.m_valueType == Type::Vector)
|
||||
AllocateDataPtr(other.GetValue<_Internal::_SimpleVector<DictionaryValue>>());
|
||||
AllocateDataPtr(other.GetValue<Internal::SimpleVector<DictionaryValue>>());
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
@ -131,7 +133,7 @@ namespace CNTK
|
|||
return m_data.m_double;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<std::is_same<T, NDShape>::value || std::is_same<T, _Internal::_SimpleVector<DictionaryValue>>::value>::type* = nullptr>
|
||||
template <typename T, typename std::enable_if<std::is_same<T, NDShape>::value || std::is_same<T, Internal::SimpleVector<DictionaryValue>>::value>::type* = nullptr>
|
||||
const T& GetValue() const
|
||||
{
|
||||
VerifyType<T>();
|
||||
|
@ -156,7 +158,7 @@ namespace CNTK
|
|||
std::is_same<T, size_t>::value ||
|
||||
std::is_same<T, double>::value ||
|
||||
std::is_same<T, NDShape>::value ||
|
||||
std::is_same<T, _Internal::_SimpleVector<DictionaryValue>>::value ||
|
||||
std::is_same<T, Internal::SimpleVector<DictionaryValue>>::value ||
|
||||
std::is_same<T, CNTK::Dictionary>::value,
|
||||
"Unsupported ValueType");
|
||||
|
||||
|
@ -168,7 +170,7 @@ namespace CNTK
|
|||
return Type::Double;
|
||||
else if (std::is_same<T, NDShape>::value)
|
||||
return Type::NDShape;
|
||||
else if (std::is_same<T, _Internal::_SimpleVector<DictionaryValue>>::value)
|
||||
else if (std::is_same<T, Internal::SimpleVector<DictionaryValue>>::value)
|
||||
return Type::Vector;
|
||||
}
|
||||
|
||||
|
@ -182,7 +184,7 @@ namespace CNTK
|
|||
template <typename T>
|
||||
void AllocateDataPtr(const T& value)
|
||||
{
|
||||
static_assert(std::is_same<T, NDShape>::value || std::is_same<T, _Internal::_SimpleVector<DictionaryValue>>::value, "AllocateDataPtr called with invalid type");
|
||||
static_assert(std::is_same<T, NDShape>::value || std::is_same<T, Internal::SimpleVector<DictionaryValue>>::value, "AllocateDataPtr called with invalid type");
|
||||
m_data.m_ptr = new T(value);
|
||||
}
|
||||
|
||||
|
@ -200,7 +202,7 @@ namespace CNTK
|
|||
if (m_valueType == Type::NDShape)
|
||||
FreePtrAsType<NDShape>();
|
||||
else if (m_valueType == Type::Vector)
|
||||
FreePtrAsType<_Internal::_SimpleVector<DictionaryValue>>();
|
||||
FreePtrAsType<Internal::SimpleVector<DictionaryValue>>();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -222,8 +224,7 @@ namespace CNTK
|
|||
~Dictionary();
|
||||
|
||||
// Disallow copy contruction and assignment
|
||||
Dictionary(const Dictionary&) = delete;
|
||||
Dictionary& operator=(const Dictionary&) = delete;
|
||||
Dictionary(const Dictionary&) = delete; Dictionary& operator=(const Dictionary&) = delete;
|
||||
|
||||
Dictionary(Dictionary&& other);
|
||||
Dictionary& operator=(Dictionary&& other);
|
||||
|
@ -266,9 +267,9 @@ namespace CNTK
|
|||
|
||||
inline DEVICEID_TYPE AsCNTKImplDeviceId(const DeviceDescriptor& device)
|
||||
{
|
||||
if (device.Type() == DeviceType::CPU)
|
||||
if (device.Type() == DeviceKind::CPU)
|
||||
return -1;
|
||||
else if (device.Type() == DeviceType::GPU)
|
||||
else if (device.Type() == DeviceKind::GPU)
|
||||
return device.Id();
|
||||
else
|
||||
NOT_IMPLEMENTED;
|
||||
|
|
|
@ -15,13 +15,14 @@ namespace CNTK
|
|||
Value::Value(const NDArrayViewPtr& data, const NDMaskPtr& mask)
|
||||
: m_data(data), m_mask(mask)
|
||||
{
|
||||
if ((mask != nullptr) && (mask->Shape().NumAxes() > data->Shape().NumAxes()))
|
||||
InvalidArgument("The number of axes of the mask of a Value object cannot exceed the number of axes of the data NDArrayView object");
|
||||
|
||||
if (mask != nullptr)
|
||||
{
|
||||
auto dataShape = data->Shape();
|
||||
auto maskShape = mask->Shape();
|
||||
|
||||
if (maskShape.NumAxes() > dataShape.NumAxes())
|
||||
InvalidArgument("The number of axes of the mask of a Value object cannot exceed the number of axes of the data NDArrayView object");
|
||||
|
||||
if (dataShape.SubShape(dataShape.NumAxes() - maskShape.NumAxes()) != maskShape)
|
||||
InvalidArgument("Invalid Value object; the data and mask are incompatible. The trailing dimensions of the data do not match the dimensions of the mask");
|
||||
}
|
||||
|
@ -49,7 +50,7 @@ namespace CNTK
|
|||
if (needsMask)
|
||||
{
|
||||
NDShape valueMaskShape = { maxSequenceLength, numSequences };
|
||||
deviceValueMask = NDMaskPtr(new NDMask(valueMaskShape, device), [](_Internal::_ReferenceCounter* ptr) {delete ptr; });
|
||||
deviceValueMask = NDMaskPtr(new NDMask(valueMaskShape, device), [](Internal::ReferenceCount* ptr) {delete ptr; });
|
||||
for (size_t i = 0; i < numSequences; ++i)
|
||||
deviceValueMask->MaskSection({ sequenceLengths[i], i }, { NDShape::InferredDimension, 1 });
|
||||
}
|
||||
|
@ -86,8 +87,8 @@ namespace CNTK
|
|||
}
|
||||
|
||||
colStarts[numSequences * maxSequenceLength] = (SparseIndexType)(nonZeroValues.size());
|
||||
NDArrayViewPtr deviceValueData(new NDArrayView(valueDataShape, colStarts.data(), rowIndices.data(), nonZeroValues.data(), nonZeroValues.size(), device, readOnly), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
return ValuePtr(new Value(deviceValueData, deviceValueMask), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
NDArrayViewPtr deviceValueData(new NDArrayView(valueDataShape, colStarts.data(), rowIndices.data(), nonZeroValues.data(), nonZeroValues.size(), device, readOnly), [](ReferenceCount* ptr) { delete ptr; });
|
||||
return ValuePtr(new Value(deviceValueData, deviceValueMask), [](ReferenceCount* ptr) { delete ptr; });
|
||||
}
|
||||
|
||||
template <typename ElementType>
|
||||
|
@ -99,7 +100,7 @@ namespace CNTK
|
|||
|
||||
size_t numSequences = sequences.size();
|
||||
NDShape valueDataShape = sampleShape.AppendShape({ maxSequenceLength, numSequences });
|
||||
NDArrayViewPtr valueData(new NDArrayView(AsDataType<ElementType>(), valueDataShape, DeviceDescriptor::CPUDevice()), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
NDArrayViewPtr valueData(new NDArrayView(AsDataType<ElementType>(), valueDataShape, DeviceDescriptor::CPUDevice()), [](ReferenceCount* ptr) { delete ptr; });
|
||||
ElementType* dataBuffer = valueData->WritableDataBuffer<ElementType>();
|
||||
for (size_t i = 0; i < numSequences; ++i)
|
||||
std::copy(sequences[i].data(), sequences[i].data() + sequences[i].size(), dataBuffer + (maxSequenceLength * i * sampleSize));
|
||||
|
@ -114,13 +115,13 @@ namespace CNTK
|
|||
}
|
||||
else
|
||||
{
|
||||
deviceValueData = NDArrayViewPtr(new NDArrayView(AsDataType<ElementType>(), valueDataShape, device), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
deviceValueData = NDArrayViewPtr(new NDArrayView(AsDataType<ElementType>(), valueDataShape, device), [](ReferenceCount* ptr) { delete ptr; });
|
||||
deviceValueData->CopyFrom(*valueData);
|
||||
if (readOnly)
|
||||
deviceValueData = deviceValueData->Alias(true);
|
||||
}
|
||||
|
||||
return ValuePtr(new Value(deviceValueData, deviceValueMask), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
return ValuePtr(new Value(deviceValueData, deviceValueMask), [](ReferenceCount* ptr) { delete ptr; });
|
||||
}
|
||||
|
||||
/*virtual*/ Value::~Value()
|
||||
|
@ -142,13 +143,13 @@ namespace CNTK
|
|||
/*virtual*/ ValuePtr Value::DeepClone(bool readOnly/* = false*/) const
|
||||
{
|
||||
// TODO: Check if this is a derived type and throw an exception in that case
|
||||
return ValuePtr(new Value(Data()->DeepClone(readOnly), (Mask() != nullptr) ? Mask()->DeepClone() : nullptr), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
return ValuePtr(new Value(Data()->DeepClone(readOnly), (Mask() != nullptr) ? Mask()->DeepClone() : nullptr), [](ReferenceCount* ptr) { delete ptr; });
|
||||
}
|
||||
|
||||
/*virtual*/ ValuePtr Value::Alias(bool readOnly/* = false*/) const
|
||||
{
|
||||
// TODO: Check if this is a derived type and throw an exception in that case
|
||||
return ValuePtr(new Value(Data()->Alias(readOnly), (Mask() != nullptr) ? Mask()->Alias() : nullptr), [](_ReferenceCounter* ptr) { delete ptr; });
|
||||
return ValuePtr(new Value(Data()->Alias(readOnly), (Mask() != nullptr) ? Mask()->Alias() : nullptr), [](ReferenceCount* ptr) { delete ptr; });
|
||||
}
|
||||
|
||||
/*virtual*/ void Value::CopyFrom(const Value& source)
|
||||
|
|
|
@ -106,22 +106,18 @@ public:
|
|||
~BestGpu();
|
||||
void Init();
|
||||
void SetAllowedDevices(const std::vector<int>& devices); // only allow certain GPUs
|
||||
bool DeviceAllowed(int device);
|
||||
void DisallowDevice(int device)
|
||||
{
|
||||
assert((device >= -1) && (device <= 31));
|
||||
|
||||
if (device < 0)
|
||||
m_disallowCPUDevice = true;
|
||||
else
|
||||
m_allowedDevices &= ~(1 << device);
|
||||
}
|
||||
bool DeviceAllowed(int deviceId);
|
||||
void DisallowUnsupportedDevices();
|
||||
void DisallowDevice(int deviceId);
|
||||
void AllowAll(); // reset to allow all GPUs (no allowed list)
|
||||
bool UseMultiple(); // using multiple GPUs?
|
||||
int GetDevice(BestGpuFlags flags = bestGpuNormal); // get a single device
|
||||
static const int AllDevices = -1; // can be used to specify all GPUs in GetDevices() call
|
||||
static const int RequeryDevices = -2; // Requery refreshing statistics and picking the same number as last query
|
||||
static const int MininumCCMajorForGpu = 3; // cntk supports GPUs with Compute Capability > 3.0
|
||||
std::vector<int> GetDevices(int number = AllDevices, BestGpuFlags flags = bestGpuNormal); // get multiple devices
|
||||
std::vector<ProcessorData *> GetProcessorData();
|
||||
|
||||
private:
|
||||
bool LockDevice(int deviceId, bool trial = true);
|
||||
};
|
||||
|
@ -156,6 +152,8 @@ static DEVICEID_TYPE SelectDevice(DEVICEID_TYPE deviceId, bool bLockGPU, const i
|
|||
{
|
||||
g_bestGpu->DisallowDevice(excludedDevices[i]);
|
||||
}
|
||||
|
||||
g_bestGpu->DisallowUnsupportedDevices();
|
||||
}
|
||||
|
||||
bestDeviceId = (DEVICEID_TYPE)g_bestGpu->GetDevice(BestGpuFlags(bLockGPU ? (bestGpuAvoidSharing | bestGpuExclusiveLock) : bestGpuAvoidSharing));
|
||||
|
@ -345,22 +343,32 @@ int BestGpu::GetDevice(BestGpuFlags bestFlags)
|
|||
void BestGpu::SetAllowedDevices(const std::vector<int>& devices)
|
||||
{
|
||||
m_allowedDevices = 0;
|
||||
for (int device : devices)
|
||||
for (int deviceId : devices)
|
||||
{
|
||||
m_allowedDevices |= (1 << device);
|
||||
m_allowedDevices |= (1 << deviceId);
|
||||
}
|
||||
}
|
||||
|
||||
// DeviceAllowed - is a particular device allowed?
|
||||
// returns: true if the device is allowed, otherwise false
|
||||
bool BestGpu::DeviceAllowed(int device)
|
||||
bool BestGpu::DeviceAllowed(int deviceId)
|
||||
{
|
||||
assert((device >= -1) && (device <= 31));
|
||||
assert((deviceId >= -1) && (deviceId <= 31));
|
||||
|
||||
if (device < 0)
|
||||
if (deviceId < 0)
|
||||
return !m_disallowCPUDevice;
|
||||
else
|
||||
return !!(m_allowedDevices & (1 << device));
|
||||
return !!(m_allowedDevices & (1 << deviceId));
|
||||
}
|
||||
|
||||
void BestGpu::DisallowDevice(int deviceId)
|
||||
{
|
||||
assert((deviceId >= -1) && (deviceId <= 31));
|
||||
|
||||
if (deviceId < 0)
|
||||
m_disallowCPUDevice = true;
|
||||
else
|
||||
m_allowedDevices &= ~(1 << deviceId);
|
||||
}
|
||||
|
||||
// AllowAll - Reset the allowed filter to allow all GPUs
|
||||
|
@ -527,6 +535,68 @@ std::vector<int> BestGpu::GetDevices(int number, BestGpuFlags p_bestFlags)
|
|||
return best; // return the array of the best GPUs
|
||||
}
|
||||
|
||||
// disallow devices wich don't comply with compute capability restriction when cntk runs with deviceId = 'auto'
|
||||
void BestGpu::DisallowUnsupportedDevices()
|
||||
{
|
||||
for (auto pd : m_procData)
|
||||
{
|
||||
if (pd->deviceProp.major < BestGpu::MininumCCMajorForGpu)
|
||||
{
|
||||
DisallowDevice(pd->deviceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GpuData GetGpuData(DEVICEID_TYPE deviceId)
|
||||
{
|
||||
std::vector<GpuData> gpusData = GetAllGpusData();
|
||||
|
||||
auto it = std::find_if(gpusData.begin(), gpusData.end(), [&deviceId](const GpuData& gpu){return gpu.deviceId == deviceId;});
|
||||
|
||||
if (it != gpusData.end())
|
||||
{
|
||||
return *it;
|
||||
}
|
||||
|
||||
return GpuData(0, 0, deviceId, 0, GpuValidity::UnknownDevice, "", 0);
|
||||
}
|
||||
|
||||
// populate a vector with data (id, major/minor version, cuda cores, name and memory) for each gpu device in the machine
|
||||
std::vector<GpuData> GetAllGpusData()
|
||||
{
|
||||
std::vector<GpuData> data;
|
||||
|
||||
auto bestGpu = make_unique<BestGpu>();
|
||||
|
||||
std::vector<ProcessorData*> processorData = bestGpu->GetProcessorData();
|
||||
|
||||
for (ProcessorData* pd : processorData)
|
||||
{
|
||||
|
||||
GpuValidity validity = GpuValidity::UnknownDevice;
|
||||
|
||||
if (pd->deviceProp.major < BestGpu::MininumCCMajorForGpu)
|
||||
{
|
||||
validity = GpuValidity::ComputeCapabilityNotSupported;
|
||||
}
|
||||
else
|
||||
{
|
||||
validity = GpuValidity::Valid;
|
||||
}
|
||||
|
||||
size_t totalMemory = pd->deviceProp.totalGlobalMem/(1024*1024); //From bytes to MBytes
|
||||
GpuData gpuData = GpuData(pd->deviceProp.major, pd->deviceProp.minor, pd->deviceId, pd->cores, validity, string(pd->deviceProp.name), totalMemory);
|
||||
data.push_back(gpuData);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
std::vector<ProcessorData*> BestGpu::GetProcessorData()
|
||||
{
|
||||
return m_procData;
|
||||
}
|
||||
|
||||
// QueryNvmlData - Query data from the Nvidia Management Library, and accumulate counters,
|
||||
// In case failure, this function simply backs out without filling in the data structure and without setting m_nvmlData.
|
||||
void BestGpu::QueryNvmlData()
|
||||
|
|
|
@ -8,15 +8,46 @@
|
|||
// #define CPUONLY // #define this to build without GPU support nor needing the SDK installed
|
||||
#include "CommonMatrix.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
// define IConfigRecord and ConfigParameters as incomplete types, in order to avoid having to include "ScriptableObjects.h" and "Config.h", as that confuses some .CU code
|
||||
namespace Microsoft { namespace MSR { namespace ScriptableObjects { struct IConfigRecord; }}}
|
||||
|
||||
namespace Microsoft { namespace MSR { namespace CNTK {
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifndef CPUONLY
|
||||
enum class GpuValidity
|
||||
{
|
||||
Valid,
|
||||
UnknownDevice,
|
||||
ComputeCapabilityNotSupported
|
||||
};
|
||||
|
||||
struct GpuData
|
||||
{
|
||||
int versionMajor;
|
||||
int versionMinor;
|
||||
int deviceId;
|
||||
int cudaCores;
|
||||
GpuValidity validity;
|
||||
string name;
|
||||
size_t totalMemory;
|
||||
GpuData(int versionMajor, int versionMinor, int deviceId, int cudaCores, GpuValidity validity, const string& name, size_t totalMemory)
|
||||
:versionMajor(versionMajor), versionMinor(versionMinor), deviceId(deviceId), cudaCores(cudaCores), validity(validity), name(name), totalMemory(totalMemory)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
std::vector<GpuData> GetAllGpusData();
|
||||
GpuData GetGpuData(DEVICEID_TYPE deviceId);
|
||||
|
||||
class ConfigParameters;
|
||||
DEVICEID_TYPE DeviceFromConfig(const ConfigParameters& config);
|
||||
DEVICEID_TYPE DeviceFromConfig(const ScriptableObjects::IConfigRecord& config);
|
||||
|
||||
#else
|
||||
template <class ConfigRecordType>
|
||||
static inline DEVICEID_TYPE DeviceFromConfig(const ConfigRecordType& /*config*/)
|
||||
|
|
|
@ -665,7 +665,8 @@ public:
|
|||
std::swap(m_strides[i], m_strides[j]);
|
||||
}
|
||||
|
||||
// Flatten the shape in place to a 2D tensor.
|
||||
// Flatten a tensor shape into a 2D tensor, where splitPoint is the first index to go into the second dimension
|
||||
// The tensor shape must be flattenable this way, i.e. each of the two index ranges must be dense.
|
||||
void FlattenTo2DInPlace(size_t splitPoint, const char* errorPrefix/* = nullptr*/)
|
||||
{
|
||||
// check & print meaningful error message
|
||||
|
|
|
@ -1423,8 +1423,8 @@ public:
|
|||
m_gradientInitialized = true;
|
||||
}
|
||||
|
||||
// resize and reset this node's gradient to a given matrix's value
|
||||
void ResetGradient(const Matrix<ElemType>& val)
|
||||
// Assign the given matrix's value to this node's gradient. The matrix sizes must match.
|
||||
void AssignGradient(const Matrix<ElemType>& val)
|
||||
{
|
||||
UpdateDataSize(Gradient());
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ template<typename BlockHandlerT> class BlockMultiplier
|
|||
// get rid of the allocation but I haven't had time to do this yet.
|
||||
static void BlockHandler128x4Thread(HandlerArgs<BlockHandlerT> ha)
|
||||
{
|
||||
//Accumulate full row results locally b/f writing to C
|
||||
// Accumulate full row results locally b/f writing to C
|
||||
VectorT* resultStorage = (VectorT*)ALIGNED_ALLOC(sizeof(VectorT) * ha.rowsPerBlock * ha.n, 16);
|
||||
memset(resultStorage, 0, sizeof(VectorT) * ha.rowsPerBlock * ha.n);
|
||||
const int blocksAtOnce = 2;
|
||||
|
@ -195,7 +195,7 @@ template<typename BlockHandlerT> class BlockMultiplier
|
|||
|
||||
int n = ha.n;
|
||||
{
|
||||
//This takes about the same amount of time as the memcpy version below.
|
||||
// This takes about the same amount of time as the memcpy version below.
|
||||
for (int c = 0; c < n; ++c)
|
||||
{
|
||||
//_mm_prefetch((char*)&(transC[RowColToOffset(c, startRow, m)]), _MM_HINT_T1);
|
||||
|
@ -297,7 +297,6 @@ template<typename BlockHandlerT> class BlockMultiplier
|
|||
|
||||
int n = ha.n;
|
||||
{
|
||||
//This takes about the same amount of time as the memcpy version below.
|
||||
for (int c = 0; c < n; ++c)
|
||||
{
|
||||
VectorT result1 = resultStorage[RowColToOffset(0, c, n)];
|
||||
|
@ -475,14 +474,14 @@ template<typename BlockHandlerT> class BlockMultiplier
|
|||
|
||||
public:
|
||||
|
||||
//Borrowed from [https://software.intel.com/en-us/forums/intel-isa-extensions/topic/285219]
|
||||
//Results in a saturated add, i.e. in the overflow case we return int_max, and in the
|
||||
//underflow we return int_min.
|
||||
//The code is clever - it uses the _mm_blendv_ps instruction to avoid branching.
|
||||
//It's based on the fact that you can only have overflow if the signs of the operands
|
||||
//are identical and different from the sign of the result.
|
||||
//The resulting code results in matrix multiplies that are a few percent slower than the non-saturating code,
|
||||
//but we avoid the wild inaccuracies resulting from over/underflow.
|
||||
// Borrowed from [https://software.intel.com/en-us/forums/intel-isa-extensions/topic/285219]
|
||||
// Results in a saturated add, i.e. in the overflow case we return int_max, and in the
|
||||
// underflow we return int_min.
|
||||
// The code is clever - it uses the _mm_blendv_ps instruction to avoid branching.
|
||||
// It's based on the fact that you can only have overflow if the signs of the operands
|
||||
// are identical and different from the sign of the result.
|
||||
// The resulting code results in matrix multiplies that are a few percent slower than the non-saturating code,
|
||||
// but we avoid the wild inaccuracies resulting from over/underflow.
|
||||
FORCEINLINE static __m128i my_adds_epi32(__m128i a, __m128i b)
|
||||
{
|
||||
__m128i int_min = _mm_set1_epi32(0x80000000);
|
||||
|
@ -499,15 +498,15 @@ template<typename BlockHandlerT> class BlockMultiplier
|
|||
//Saturated horizontal add
|
||||
FORCEINLINE static int32_t my_hadd(__m128i hAddMe)
|
||||
{
|
||||
//We have ABCD, we want A + B + C +D.
|
||||
//Shuffle to get BADC
|
||||
// We have ABCD, we want A + B + C +D.
|
||||
// Shuffle to get BADC
|
||||
__m128i shuff1 = _mm_shuffle_epi32(hAddMe, _MM_SHUFFLE(1, 0, 3, 2));
|
||||
__m128i res1 = my_adds_epi32(hAddMe, shuff1);
|
||||
//Now we have
|
||||
//A+B B+A, C+D D+C, so shuffle and add once more
|
||||
// Now we have
|
||||
// A+B B+A, C+D D+C, so shuffle and add once more
|
||||
__m128i shuff2 = _mm_shuffle_epi32(res1, _MM_SHUFFLE(0, 1, 2, 3));
|
||||
//This gives us
|
||||
//D+C A+B B+A C+D
|
||||
// This gives us
|
||||
// D+C A+B B+A C+D
|
||||
__m128i res2 = my_adds_epi32(res1, shuff2);
|
||||
return _mm_extract_epi32(res2, 0);
|
||||
}
|
||||
|
@ -560,6 +559,7 @@ template<typename BlockHandlerT> class BlockMultiplier
|
|||
m_pPool.reset(new StdThreadPool<HandlerArgs<BlockHandlerT>>(threads));
|
||||
#else
|
||||
#ifdef OPENMPTHREAD
|
||||
m_oldNumThreads = omp_get_num_threads();
|
||||
omp_set_num_threads(threads);
|
||||
#endif
|
||||
#endif
|
||||
|
@ -568,16 +568,18 @@ template<typename BlockHandlerT> class BlockMultiplier
|
|||
~BlockMultiplier()
|
||||
{
|
||||
BlockHandlerT::FreePreparedB(m_pBlockHandlerBInfo);
|
||||
omp_set_num_threads(m_oldNumThreads);
|
||||
}
|
||||
static ScalarAT* CreateMatrixA(int m, int n, ScalarAT initVal = 0);
|
||||
static ScalarBT* CreateMatrixB(int m, int n, ScalarBT initVal = 0);
|
||||
static int32_t* CreateMatrixC(int m, int n, int32_t initVal = 0);
|
||||
ScalarBT* PrepareB(ScalarBT* oldB, int k, int n);
|
||||
template<typename ScalarT> static void FreeMatrix(ScalarT* freeMe) { FreeAlignedMatrix<ScalarT>(freeMe); }
|
||||
//We assume B has been rewritten in block order.
|
||||
//For now we assume m, k and n are all multiples of kernelsize.
|
||||
// We assume B has been rewritten in block order.
|
||||
// For now we assume m, k and n are all multiples of kernelsize.
|
||||
void MultiplyMatrices(ScalarAT* A, int m, int k, ScalarBT* B, int n, int32_t* C, ScalarAT alpha = 1, ScalarBT beta = 0);
|
||||
static const int MAXRANGE = 1 << 13;
|
||||
int m_oldNumThreads;
|
||||
};
|
||||
|
||||
// Instantiate block multipliers
|
||||
|
@ -606,8 +608,8 @@ template<typename BlockHandlerT> int32_t* BlockMultiplier<BlockHandlerT>::Create
|
|||
template<typename BlockHandlerT> FORCEINLINE int BlockMultiplier<BlockHandlerT>::referenceKernel(ScalarAT* A,
|
||||
ScalarBT* B, int blockSize)
|
||||
{
|
||||
//For now just use regular instructions
|
||||
//until we have the breakdown figured out.
|
||||
// For now just use regular instructions
|
||||
// until we have the breakdown figured out.
|
||||
int accum = 0;
|
||||
for (int i = 0; i < blockSize; ++i)
|
||||
{
|
||||
|
@ -616,8 +618,8 @@ template<typename BlockHandlerT> FORCEINLINE int BlockMultiplier<BlockHandlerT>:
|
|||
return accum;
|
||||
}
|
||||
|
||||
//Rewrites B in Block order so that memory accesses to B will be sequential.
|
||||
//See comments on RewriteBInBlockOrder for details.
|
||||
// Rewrites B in Block order so that memory accesses to B will be sequential.
|
||||
// See comments on RewriteBInBlockOrder for details.
|
||||
template<typename BlockHandlerT> typename BlockMultiplier<BlockHandlerT>::ScalarBT* BlockMultiplier<BlockHandlerT>::PrepareB(ScalarBT* oldB, int k, int n)
|
||||
{
|
||||
ScalarBT* newB = CreateMatrixB(k, n);
|
||||
|
@ -651,37 +653,37 @@ template<typename BlockHandlerT> typename BlockMultiplier<BlockHandlerT>::Scalar
|
|||
return newB;
|
||||
}
|
||||
|
||||
//A version of RewriteBInBlockOrder that allows for multiple decreasing block sizes
|
||||
//(Which is necessary for letting us handle arbitrarily-sized matrices). On the first call, set kOffset to zero, and
|
||||
//newB to the beginning of the newly allocated B array.
|
||||
//We return a pointer to the next writable element in newB, and kOffset gets the new offset into the shared dimension.
|
||||
// A version of RewriteBInBlockOrder that allows for multiple decreasing block sizes
|
||||
// (Which is necessary for letting us handle arbitrarily-sized matrices). On the first call, set kOffset to zero, and
|
||||
// newB to the beginning of the newly allocated B array.
|
||||
// We return a pointer to the next writable element in newB, and kOffset gets the new offset into the shared dimension.
|
||||
|
||||
//So if you have blocks of size 128 and 64, do something like this:
|
||||
//short* newB = alloc_b();
|
||||
//int kOffset=0;
|
||||
//int retBlockSize = firstBlockSize;
|
||||
//(Write out the blocks up to k=128)
|
||||
//short* nextB = RewriteBInBlockOrder(oldB, newB, k, n, 128, *kOffset);
|
||||
//short* lastB = RewriteBInBlockOrder(oldB, nextB, k, n, 64, &kOffset);
|
||||
// So if you have blocks of size 128 and 64, do something like this:
|
||||
// short* newB = alloc_b();
|
||||
// int kOffset=0;
|
||||
// int retBlockSize = firstBlockSize;
|
||||
// (Write out the blocks up to k=128)
|
||||
// short* nextB = RewriteBInBlockOrder(oldB, newB, k, n, 128, *kOffset);
|
||||
// short* lastB = RewriteBInBlockOrder(oldB, nextB, k, n, 64, &kOffset);
|
||||
|
||||
//For each block, the logic is as follows:
|
||||
//Given a block size of 2 and a matrix that looks like this:
|
||||
// For each block, the logic is as follows:
|
||||
// Given a block size of 2 and a matrix that looks like this:
|
||||
// B00 B01 B02 B03
|
||||
// B10 B11 B12 B13
|
||||
// B20 B21 B22 B23
|
||||
// B30 B31 B32 B33
|
||||
//.. we will rewrite it like this
|
||||
// .. we will rewrite it like this
|
||||
// B00 B10 B01 B11 B02 B12 B03 B13 //The first block of columns 0,1,2, and 3.
|
||||
//B20 B30 B21 B31 B22 B32 B23 B33 //The second block of columns, 0, 1, 2, and 3.
|
||||
// B20 B30 B21 B31 B22 B32 B23 B33 //The second block of columns, 0, 1, 2, and 3.
|
||||
|
||||
//So each "row" of the new matrix (block size * num_original_cols) contains all of the values that
|
||||
//will be multiplied with block zero of a given row.
|
||||
//Column offsets within the row can be computed by (block_size * col_offset).
|
||||
// So each "row" of the new matrix (block size * num_original_cols) contains all of the values that
|
||||
// will be multiplied with block zero of a given row.
|
||||
// Column offsets within the row can be computed by (block_size * col_offset).
|
||||
|
||||
//Given the original B matrix, we restructure it so that we will access all of its elements in block order.
|
||||
//That way we can load in blocksize elements from A, then read in the corresponding elements from each
|
||||
//column of B in sequential order.
|
||||
//Old, replaced with fn below, keeping around for now for reference.
|
||||
// Given the original B matrix, we restructure it so that we will access all of its elements in block order.
|
||||
// That way we can load in blocksize elements from A, then read in the corresponding elements from each
|
||||
// column of B in sequential order.
|
||||
// Old, replaced with fn below, keeping around for now for reference.
|
||||
template<typename BlockHandlerT> typename BlockMultiplier<BlockHandlerT>::ScalarBT* BlockMultiplier<BlockHandlerT>::RewriteBInBlockOrder(ScalarBT* oldB, ScalarBT* newB, int k,
|
||||
int n, int blockSize, int* kOffset)
|
||||
{
|
||||
|
@ -689,7 +691,7 @@ template<typename BlockHandlerT> typename BlockMultiplier<BlockHandlerT>::Scalar
|
|||
int numBlocks = (k - *kOffset) / blockSize;
|
||||
for (int b = 0; b < numBlocks; ++b)
|
||||
{
|
||||
//row offset to beginning of block
|
||||
// Row offset to beginning of block
|
||||
int blockOffset = *kOffset + (b * blockSize);
|
||||
for (int c = 0; c < n; ++c)
|
||||
{
|
||||
|
@ -700,28 +702,28 @@ template<typename BlockHandlerT> typename BlockMultiplier<BlockHandlerT>::Scalar
|
|||
}
|
||||
}
|
||||
}
|
||||
//Bump offset for next level down
|
||||
// Bump offset for next level down
|
||||
*kOffset += (numBlocks * blockSize);
|
||||
//Return ptr to next value to be written
|
||||
// Return ptr to next value to be written
|
||||
return curr;
|
||||
}
|
||||
|
||||
//We can also reorder A, pulling in multiple rows at once.
|
||||
//So while the input looks like this in memory:
|
||||
// We can also reorder A, pulling in multiple rows at once.
|
||||
// So while the input looks like this in memory:
|
||||
// Row1Block1 Row1Block2 Row1Block3
|
||||
// Row2Block1 Row2Block2 Row2Block3
|
||||
// Row3Block1 Row3Block2 Row3Block3
|
||||
// Row4Block1 Row4Block2 Row4Block3
|
||||
//
|
||||
// we want the rewritten array to look like this (assuming 2 rows per block):
|
||||
//Row1Block1 Row2Block1 Row1Block2 Row2Block2 Row1Block3 Row2Block3
|
||||
//Row3Block1 Row4Block1 Row3Block2 Row4Block2 Row3Block3 Row4Block3
|
||||
// Row1Block1 Row2Block1 Row1Block2 Row2Block2 Row1Block3 Row2Block3
|
||||
// Row3Block1 Row4Block1 Row3Block2 Row4Block2 Row3Block3 Row4Block3
|
||||
|
||||
//length = 2 (rows per block) * 3 (blocks per row)
|
||||
// length = 2 (rows per block) * 3 (blocks per row)
|
||||
|
||||
//So the first "row" contains the first rowsPerBlock rows in block order.
|
||||
//We can index into the start of block b in a row via (b * blockSize * rowsPerBlock)
|
||||
//blockSize is the size of our dot product kernel.
|
||||
// So the first "row" contains the first rowsPerBlock rows in block order.
|
||||
// We can index into the start of block b in a row via (b * blockSize * rowsPerBlock)
|
||||
// blockSize is the size of our dot product kernel.
|
||||
template<typename BlockHandlerT> void BlockMultiplier<BlockHandlerT>::RewriteAInBlockOrder(ScalarAT* A, ScalarAT* newA, int m,
|
||||
int k, int /*blockSize*/, int rowsPerBlock)
|
||||
{
|
||||
|
@ -774,7 +776,7 @@ template<typename BlockHandlerT> typename BlockMultiplier<BlockHandlerT>::Scalar
|
|||
}
|
||||
|
||||
|
||||
//I tried parallelizing this and got no speedup - that doesn't really make sense though.
|
||||
// I tried parallelizing this and got no speedup - that doesn't really make sense though.
|
||||
template<typename BlockHandlerT> typename BlockMultiplier<BlockHandlerT>::ScalarAT* BlockMultiplier<BlockHandlerT>::RewriteAInBlockOrder2(ScalarAT* A, ScalarAT* newA,
|
||||
int m, int k, int blockSize, int rowsPerBlock, int* pKOffset)
|
||||
{
|
||||
|
@ -820,8 +822,9 @@ template<typename BlockHandlerT>struct BlockInfo
|
|||
std::function<void (HandlerArgs<BlockHandlerT>)> oneFn;
|
||||
};
|
||||
|
||||
//We assume B has been rewritten in block order.
|
||||
//For now we assume m, k and n are all multiples of kernelsize.
|
||||
|
||||
// We assume B has been rewritten in block order.
|
||||
// We assume C has been zeroed out.
|
||||
template<typename BlockHandlerT> void BlockMultiplier<BlockHandlerT>::MultiplyMatrices(ScalarAT* A, int m, int k, ScalarBT* B, int n,
|
||||
int32_t* C, ScalarAT alpha, ScalarBT beta)
|
||||
{
|
||||
|
@ -832,15 +835,24 @@ template<typename BlockHandlerT> void BlockMultiplier<BlockHandlerT>::MultiplyMa
|
|||
// in the openmp case, but I have not tested this scenario so I'm leaving it in for now.
|
||||
std::lock_guard<std::mutex> lock(m_MultiplyMut);
|
||||
{
|
||||
// We want to multithread to the extent possible. When batch size is small this
|
||||
// means doing a row at a time so we can take advantage of multiple procs.
|
||||
// But only row sizes 1 and 4 are supported so far (should be fixed by codegen).
|
||||
int rowsPerBlock = m / m_numThreads;
|
||||
if (rowsPerBlock < 4)
|
||||
rowsPerBlock = 1;
|
||||
if (rowsPerBlock > 4)
|
||||
rowsPerBlock = 4;
|
||||
|
||||
// Fall back to row at a time if we end up with an invalid # of rows at a time
|
||||
// TODO: We should always do 4 rows at a time if it makes sense from a threading standpoint
|
||||
// since it is significantly more efficient. So if we have e.g. 7 rows, we should do
|
||||
// one set of four rows at a time and then three single rows. This however will require
|
||||
// changes to this function, RewriteAInBlockOrder and RowToColOffsetRewrittenA, so for now
|
||||
// we are silently backing off to row at a time.
|
||||
if (m % rowsPerBlock != 0)
|
||||
{
|
||||
throw new std::runtime_error("Error: m must be < 4 or a multiple of 4.");
|
||||
rowsPerBlock = 1;
|
||||
}
|
||||
|
||||
if (alpha != 1 || beta != 0)
|
||||
|
@ -890,10 +902,6 @@ template<typename BlockHandlerT> void BlockMultiplier<BlockHandlerT>::MultiplyMa
|
|||
|
||||
std::vector<BlockInfo<BlockHandlerT>*> blockInfos(5);
|
||||
|
||||
|
||||
//std::function<void __cdecl(HandlerArgs<BlockHandlerT>)> fourFn = BlockHandler128x4Thread;
|
||||
//std::function<void __cdecl(HandlerArgs<BlockHandlerT>)> oneFn = BlockHandler128x1Thread;
|
||||
|
||||
BlockInfo<BlockHandlerT> bi128(blocks128, k128, 0, 0, fn128x4, fn128x1);
|
||||
BlockInfo<BlockHandlerT> bi64(blocks64, k64, offsetA64, offsetB64, fn64x4, fn64x1);
|
||||
BlockInfo<BlockHandlerT> bi32(blocks32, k32, offsetA32, offsetB32, fn32x4, fn32x1);
|
||||
|
@ -911,8 +919,6 @@ template<typename BlockHandlerT> void BlockMultiplier<BlockHandlerT>::MultiplyMa
|
|||
if ( currBlockInfo.blockCnt > 0)
|
||||
{
|
||||
HandlerArgs<BlockHandlerT> ha;
|
||||
|
||||
|
||||
ha.blocks = currBlockInfo.blockCnt;
|
||||
ha.m = m;
|
||||
ha.k = currBlockInfo.k;
|
||||
|
@ -920,7 +926,6 @@ template<typename BlockHandlerT> void BlockMultiplier<BlockHandlerT>::MultiplyMa
|
|||
ha.newA = newA + currBlockInfo.offsetA;
|
||||
ha.B = B + currBlockInfo.offsetB;
|
||||
ha.transC = C;
|
||||
|
||||
ha.rowsPerThread = m / m_numThreads;
|
||||
ha.rowsPerBlock = rowsPerBlock;
|
||||
ha.pBlockPreparedB = m_pBlockHandlerBInfo;
|
||||
|
@ -999,4 +1004,4 @@ template<typename BlockHandlerT> void BlockMultiplier<BlockHandlerT>::MultiplyMa
|
|||
|
||||
|
||||
|
||||
}}}//end namespace
|
||||
}}}// end namespace
|
||||
|
|
|
@ -110,9 +110,6 @@
|
|||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="uci_to_cntk_text_format_converter.py" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
|
@ -47,13 +47,5 @@
|
|||
<Filter Include="Common\Include">
|
||||
<UniqueIdentifier>{C6F55578-121A-4D7C-8F57-4172BC5C463B}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Scripts">
|
||||
<UniqueIdentifier>{cd70d891-88aa-40a4-8e47-0e31e4cac48e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="uci_to_cntk_text_format_converter.py">
|
||||
<Filter>Scripts</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
|
||||
namespace Microsoft { namespace MSR { namespace CNTK {
|
||||
|
||||
inline bool IsDigit(char c)
|
||||
{
|
||||
return '0' <= c && c <= '9';
|
||||
}
|
||||
|
||||
enum State
|
||||
{
|
||||
Init = 0,
|
||||
|
@ -38,7 +43,7 @@ public:
|
|||
void GetSequence(size_t sequenceId, std::vector<SequenceDataPtr>& result) override;
|
||||
|
||||
// A map from sequence ids to the sequence data.
|
||||
std::map<size_t, SequenceBuffer> m_sequenceMap;
|
||||
std::vector<SequenceBuffer> m_sequenceMap;
|
||||
|
||||
// chunk id (copied from the descriptor)
|
||||
ChunkIdType m_id;
|
||||
|
@ -234,40 +239,11 @@ TextParser<ElemType>::TextDataChunk::TextDataChunk(const ChunkDescriptor& descri
|
|||
template <class ElemType>
|
||||
void TextParser<ElemType>::TextDataChunk::GetSequence(size_t sequenceId, std::vector<SequenceDataPtr>& result)
|
||||
{
|
||||
auto it = m_sequenceMap.find(sequenceId);
|
||||
assert(it != m_sequenceMap.end());
|
||||
assert(sequenceId < m_sequenceMap.size());
|
||||
result.reserve(m_parser->m_streamInfos.size());
|
||||
const auto& sequenceData = it->second;
|
||||
for (size_t j = 0; j < m_parser->m_streamInfos.size(); ++j)
|
||||
{
|
||||
InputStreamBuffer* input = sequenceData[j].get();
|
||||
const StreamInfo& stream = m_parser->m_streamInfos[j];
|
||||
SequenceDataPtr data;
|
||||
if (stream.m_type == StorageType::dense)
|
||||
{
|
||||
auto denseData = make_shared<DenseSequenceData>();
|
||||
denseData->m_sampleLayout = m_parser->m_streams[j]->m_sampleLayout;
|
||||
data = denseData;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto sparseData = make_shared<SparseSequenceData>();
|
||||
SparseInputStreamBuffer* sparseInput = static_cast<SparseInputStreamBuffer*>(input);
|
||||
sparseData->m_indices = sparseInput->m_indices.data();
|
||||
sparseData->m_nnzCounts.reserve(sparseInput->m_nnzCounts.size());
|
||||
copy(sparseInput->m_nnzCounts.begin(), sparseInput->m_nnzCounts.end(),
|
||||
back_inserter(sparseData->m_nnzCounts));
|
||||
sparseData->m_totalNnzCount = sparseInput->m_totalNnzCount;
|
||||
assert(input->m_numberOfSamples == sparseInput->m_nnzCounts.size());
|
||||
data = sparseData;
|
||||
}
|
||||
|
||||
data->m_data = input->m_buffer.data();
|
||||
data->m_numberOfSamples = input->m_numberOfSamples;
|
||||
data->m_chunk = shared_from_this();
|
||||
data->m_id = sequenceId;
|
||||
result.push_back(data);
|
||||
}
|
||||
const auto& sequenceData = m_sequenceMap[sequenceId];
|
||||
result.insert(result.end(), sequenceData.begin(), sequenceData.end());
|
||||
}
|
||||
|
||||
template <class ElemType>
|
||||
|
@ -292,11 +268,10 @@ ChunkPtr TextParser<ElemType>::GetChunk(ChunkIdType chunkId)
|
|||
template <class ElemType>
|
||||
void TextParser<ElemType>::LoadChunk(TextChunkPtr& chunk, const ChunkDescriptor& descriptor)
|
||||
{
|
||||
chunk->m_sequenceMap.resize(descriptor.m_sequences.size());
|
||||
for (const auto& sequenceDescriptor : descriptor.m_sequences)
|
||||
{
|
||||
chunk->m_sequenceMap.insert(make_pair(
|
||||
sequenceDescriptor.m_id,
|
||||
LoadSequence(sequenceDescriptor)));
|
||||
chunk->m_sequenceMap[sequenceDescriptor.m_id] = LoadSequence(sequenceDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -480,13 +455,39 @@ typename TextParser<ElemType>::SequenceBuffer TextParser<ElemType>::LoadSequence
|
|||
GetSequenceKey(sequenceDsc).c_str(), GetFileInfo().c_str(), numRowsRead, expectedRowCount);
|
||||
}
|
||||
|
||||
FillSequenceMetadata(sequence, sequenceDsc.m_id);
|
||||
return sequence;
|
||||
}
|
||||
|
||||
template<class ElemType>
|
||||
void TextParser<ElemType>::FillSequenceMetadata(SequenceBuffer& sequenceData, size_t sequenceId)
|
||||
{
|
||||
for (size_t j = 0; j < m_streamInfos.size(); ++j)
|
||||
{
|
||||
const StreamInfo& stream = m_streamInfos[j];
|
||||
SequenceDataBase* data = sequenceData[j].get();
|
||||
if (stream.m_type == StorageType::dense)
|
||||
{
|
||||
auto denseData = static_cast<DenseInputStreamBuffer*>(data);
|
||||
denseData->m_sampleLayout = m_streams[j]->m_sampleLayout;
|
||||
data->m_data = denseData->m_buffer.data();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto sparseData = static_cast<SparseInputStreamBuffer*>(data);
|
||||
sparseData->m_indices = sparseData->m_indicesBuffer.data();
|
||||
assert(data->m_numberOfSamples == sparseData->m_nnzCounts.size());
|
||||
data->m_data = sparseData->m_buffer.data();
|
||||
}
|
||||
|
||||
data->m_id = sequenceId;
|
||||
}
|
||||
}
|
||||
|
||||
template <class ElemType>
|
||||
bool TextParser<ElemType>::TryReadRow(SequenceBuffer& sequence, size_t& bytesToRead)
|
||||
{
|
||||
while (bytesToRead && CanRead() && isdigit(*m_pos))
|
||||
while (bytesToRead && CanRead() && IsDigit(*m_pos))
|
||||
{
|
||||
// skip sequence ids
|
||||
++m_pos;
|
||||
|
@ -616,7 +617,7 @@ bool TextParser<ElemType>::TryReadSample(SequenceBuffer& sequence, size_t& bytes
|
|||
{
|
||||
SparseInputStreamBuffer* data = reinterpret_cast<SparseInputStreamBuffer*>(sequence[id].get());
|
||||
vector<ElemType>& values = data->m_buffer;
|
||||
vector<IndexType>& indices = data->m_indices;
|
||||
vector<IndexType>& indices = data->m_indicesBuffer;
|
||||
assert(values.size() == indices.size());
|
||||
size_t size = values.size();
|
||||
if (!TryReadSparseSample(values, indices, stream.m_sampleDimension, bytesToRead))
|
||||
|
@ -919,7 +920,7 @@ bool TextParser<ElemType>::TryReadUint64(size_t& value, size_t& bytesToRead)
|
|||
{
|
||||
char c = *m_pos;
|
||||
|
||||
if (!isdigit(c))
|
||||
if (!IsDigit(c))
|
||||
{
|
||||
return found;
|
||||
}
|
||||
|
@ -977,7 +978,7 @@ bool TextParser<ElemType>::TryReadRealNumber(ElemType& value, size_t& bytesToRea
|
|||
{
|
||||
case State::Init:
|
||||
// the number must either start with a number or a sign
|
||||
if (isdigit(c))
|
||||
if (IsDigit(c))
|
||||
{
|
||||
state = IntegralPart;
|
||||
number = (c - '0');
|
||||
|
@ -1001,7 +1002,7 @@ bool TextParser<ElemType>::TryReadRealNumber(ElemType& value, size_t& bytesToRea
|
|||
break;
|
||||
case Sign:
|
||||
// the sign must be followed by a number
|
||||
if (isdigit(c))
|
||||
if (IsDigit(c))
|
||||
{
|
||||
state = IntegralPart;
|
||||
number = (c - '0');
|
||||
|
@ -1019,7 +1020,7 @@ bool TextParser<ElemType>::TryReadRealNumber(ElemType& value, size_t& bytesToRea
|
|||
}
|
||||
break;
|
||||
case IntegralPart:
|
||||
if (isdigit(c))
|
||||
if (IsDigit(c))
|
||||
{
|
||||
number = number * 10 + (c - '0');
|
||||
}
|
||||
|
@ -1040,7 +1041,7 @@ bool TextParser<ElemType>::TryReadRealNumber(ElemType& value, size_t& bytesToRea
|
|||
}
|
||||
break;
|
||||
case Period:
|
||||
if (isdigit(c))
|
||||
if (IsDigit(c))
|
||||
{
|
||||
state = FractionalPart;
|
||||
coefficient = number;
|
||||
|
@ -1054,7 +1055,7 @@ bool TextParser<ElemType>::TryReadRealNumber(ElemType& value, size_t& bytesToRea
|
|||
}
|
||||
break;
|
||||
case FractionalPart:
|
||||
if (isdigit(c))
|
||||
if (IsDigit(c))
|
||||
{
|
||||
// TODO: ignore if number of precision digits > FLT_[MANT_]DIG/DBL_[MANT_]DIG
|
||||
// no state change
|
||||
|
@ -1079,7 +1080,7 @@ bool TextParser<ElemType>::TryReadRealNumber(ElemType& value, size_t& bytesToRea
|
|||
break;
|
||||
case TheLetterE:
|
||||
// followed with optional minus or plus sign and nonempty sequence of decimal digits
|
||||
if (isdigit(c))
|
||||
if (IsDigit(c))
|
||||
{
|
||||
state = Exponent;
|
||||
negative = false;
|
||||
|
@ -1104,7 +1105,7 @@ bool TextParser<ElemType>::TryReadRealNumber(ElemType& value, size_t& bytesToRea
|
|||
break;
|
||||
case ExponentSign:
|
||||
// exponent sign must be followed by a number
|
||||
if (isdigit(c))
|
||||
if (IsDigit(c))
|
||||
{
|
||||
state = Exponent;
|
||||
number = (c - '0');
|
||||
|
@ -1122,7 +1123,7 @@ bool TextParser<ElemType>::TryReadRealNumber(ElemType& value, size_t& bytesToRea
|
|||
}
|
||||
break;
|
||||
case Exponent:
|
||||
if (isdigit(c))
|
||||
if (IsDigit(c))
|
||||
{
|
||||
// no state change
|
||||
number = number * 10 + (c - '0');
|
||||
|
|
|
@ -42,37 +42,33 @@ private:
|
|||
// Builds an index of the input data.
|
||||
void Initialize();
|
||||
|
||||
// A buffer to keep data for all samples in a (variable length) sequence
|
||||
// from a single input stream.
|
||||
struct InputStreamBuffer
|
||||
{
|
||||
virtual ~InputStreamBuffer() { };
|
||||
|
||||
uint32_t m_numberOfSamples = 0;
|
||||
std::vector<ElemType> m_buffer;
|
||||
};
|
||||
|
||||
struct DenseInputStreamBuffer : InputStreamBuffer
|
||||
struct DenseInputStreamBuffer : DenseSequenceData
|
||||
{
|
||||
// capacity = expected number of samples * sample size
|
||||
DenseInputStreamBuffer(size_t capacity)
|
||||
{
|
||||
InputStreamBuffer::m_buffer.reserve(capacity);
|
||||
m_buffer.reserve(capacity);
|
||||
}
|
||||
|
||||
std::vector<ElemType> m_buffer;
|
||||
};
|
||||
|
||||
// In case of sparse input, we also need a vector of
|
||||
// indices (one index for each input value) and a vector
|
||||
// of NNZ counts (one for each sample).
|
||||
struct SparseInputStreamBuffer : InputStreamBuffer
|
||||
struct SparseInputStreamBuffer : SparseSequenceData
|
||||
{
|
||||
IndexType m_totalNnzCount = 0;
|
||||
std::vector<IndexType> m_indices;
|
||||
std::vector<IndexType> m_nnzCounts;
|
||||
SparseInputStreamBuffer()
|
||||
{
|
||||
m_totalNnzCount = 0;
|
||||
}
|
||||
|
||||
std::vector<IndexType> m_indicesBuffer;
|
||||
std::vector<ElemType> m_buffer;
|
||||
};
|
||||
|
||||
// A sequence buffer is a vector that contains an input buffer for each input stream.
|
||||
typedef std::vector<std::unique_ptr<InputStreamBuffer>> SequenceBuffer;
|
||||
// A sequence buffer is a vector that contains sequence data for each input stream.
|
||||
typedef std::vector<SequenceDataPtr> SequenceBuffer;
|
||||
|
||||
// A chunk of input data in the text format.
|
||||
class TextDataChunk;
|
||||
|
@ -176,6 +172,9 @@ private:
|
|||
|
||||
TextParser(CorpusDescriptorPtr corpus, const std::wstring& filename, const vector<StreamDescriptor>& streams);
|
||||
|
||||
// Fills some metadata members to be conformant to the exposed SequenceData interface.
|
||||
void FillSequenceMetadata(SequenceBuffer& sequenceBuffer, size_t sequenceId);
|
||||
|
||||
void SetTraceLevel(unsigned int traceLevel);
|
||||
|
||||
void SetMaxAllowedErrors(unsigned int maxErrors);
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace Microsoft { namespace MSR { namespace CNTK {
|
|||
|
||||
const char ESCAPE_SYMBOL = '#';
|
||||
|
||||
const auto BUFFER_SIZE = 256 * 1024;
|
||||
const auto BUFFER_SIZE = 2 * 1024 * 1024;
|
||||
|
||||
inline bool isPrintable(char c)
|
||||
{
|
||||
|
|
|
@ -30,18 +30,6 @@
|
|||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<HasOpenCV>false</HasOpenCV>
|
||||
<HasOpenCV Condition="Exists('$(OPENCV_PATH)')">true</HasOpenCV>
|
||||
<UseZip>false</UseZip>
|
||||
<UseZip Condition="Exists('$(ZLIB_PATH)')">true</UseZip>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(UseZip)">
|
||||
<ZipInclude>$(ZLIB_PATH)\include;$(ZLIB_PATH)\lib\libzip\include;</ZipInclude>
|
||||
<ZipDefine>USE_ZIP</ZipDefine>
|
||||
<ZipLibPath>$(ZLIB_PATH)\lib;</ZipLibPath>
|
||||
<ZipLibs>zlib.lib;zip.lib;</ZipLibs>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(DebugBuild)" Label="Configuration">
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
|
@ -54,9 +42,6 @@
|
|||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<OpenCVLib Condition="$(HasOpenCV)">opencv_world300.lib</OpenCVLib>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(DebugBuild)">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
|
@ -76,22 +61,23 @@
|
|||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ReaderLib.lib;Common.lib;Math.lib;$(OpenCVLib);$(ZipLibs);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>ReaderLib.lib;Common.lib;Math.lib;$(OpenCvLib);$(ZipLibs);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>if "$(HasOpenCv)" == "true" xcopy /I /D /Y "$(OPENCV_PATH)\x64\vc12\bin\opencv_world300.dll" "$(TargetDir)"
|
||||
if "$(UseZip)" == "true" xcopy /I /D /Y "$(ZLIB_PATH)\bin\zip.dll" "$(TargetDir)"
|
||||
if "$(UseZip)" == "true" if exist "$(ZLIB_PATH)\bin\zlib1.dll" (xcopy /I /D /Y "$(ZLIB_PATH)\bin\zlib1.dll" "$(TargetDir)") else (copy /Y "$(ZLIB_PATH)\bin\zlib.dll" "$(TargetDir)\zlib1.dll")
|
||||
</Command>
|
||||
<Command>
|
||||
if "$(HasOpenCv)" == "true" xcopy /I /D /Y "$(OpenCvBinPath)\$(OpenCvWorld).dll" "$(TargetDir)"
|
||||
if "$(UseZip)" == "true" xcopy /I /D /Y "$(ZLIB_PATH)\bin\zip.dll" "$(TargetDir)"
|
||||
if "$(UseZip)" == "true" if exist "$(ZLIB_PATH)\bin\zlib1.dll" (xcopy /I /D /Y "$(ZLIB_PATH)\bin\zlib1.dll" "$(TargetDir)") else (copy /Y "$(ZLIB_PATH)\bin\zlib.dll" "$(TargetDir)\zlib1.dll")
|
||||
</Command>
|
||||
<Message>Copying dependencies</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)Source\Common\Include;$(SolutionDir)Source\Math;$(OPENCV_PATH)\include;$(ZipInclude);$(SolutionDir)Source\Readers\ReaderLib</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)Source\Common\Include;$(SolutionDir)Source\Math;$(OpenCvInclude);$(ZipInclude);$(SolutionDir)Source\Readers\ReaderLib</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(OutDir);$(OPENCV_PATH)\x64\vc12\lib;$(ZipLibPath)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir);$(OpenCvLibPath);$(ZipLibPath)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="$(DebugBuild)">
|
||||
|
@ -131,7 +117,7 @@ if "$(UseZip)" == "true" if exist "$(ZLIB_PATH)\bin\zlib1.dll" (xcopy /I /D /Y "
|
|||
<ClCompile Include="ImageDataDeserializer.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="Exports.cpp">
|
||||
<ExcludedFromBuild Condition="!$(HasOpenCV)">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="!$(HasOpenCv)">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ImageReader.cpp" />
|
||||
<ClCompile Include="ImageTransformers.cpp" />
|
||||
|
@ -141,10 +127,10 @@ if "$(UseZip)" == "true" if exist "$(ZLIB_PATH)\bin\zlib1.dll" (xcopy /I /D /Y "
|
|||
<ClCompile Include="ZipByteReader.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<Target Name="Build" Condition="$(HasOpenCV)" Outputs="$(TargetPath)" DependsOnTargets="$(BuildDependsOn)" />
|
||||
<Target Name="Build" Condition="$(HasOpenCv)" Outputs="$(TargetPath)" DependsOnTargets="$(BuildDependsOn)" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
<Target Name="CheckDependencies">
|
||||
<Warning Condition="!$(HasOpenCV)" Text="ImageReader requires the OpenCV library to build. Please see https://github.com/Microsoft/CNTK/wiki/Setup-CNTK-on-Windows#opencv for installation instructions." />
|
||||
<Warning Condition="!$(HasOpenCv)" Text="ImageReader requires the OpenCV library to build. Please see https://github.com/Microsoft/CNTK/wiki/Setup-CNTK-on-Windows#opencv for installation instructions." />
|
||||
<Warning Condition="!$(UseZip)" Text="zlib and libzip libraries were not found, ImageReader will be built without zip container support. Please see https://github.com/Microsoft/CNTK/wiki/Setup-CNTK-on-Windows#libzip for installation instructions." />
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
|
@ -102,9 +102,6 @@ void BlockRandomizer::PrepareNewSweepIfNeeded(size_t samplePosition)
|
|||
|
||||
// Resetting sequence randomizer.
|
||||
m_sequenceRandomizer->Reset(m_sweep + 1);
|
||||
|
||||
// Unloading all chunk data from memory.
|
||||
m_chunks.clear();
|
||||
m_lastSeenChunkId = CHUNKID_MAX;
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +139,7 @@ Sequences BlockRandomizer::GetNextSequences(size_t sampleCount)
|
|||
auto process = [&](int i) -> void {
|
||||
const auto& description = decimated[i];
|
||||
std::vector<SequenceDataPtr> sequence;
|
||||
auto it = m_chunks.find(description.m_chunk->m_chunkId);
|
||||
auto it = m_chunks.find(description.m_chunk->m_original->m_id);
|
||||
if (it == m_chunks.end())
|
||||
{
|
||||
LogicError("Invalid chunk requested.");
|
||||
|
@ -253,6 +250,11 @@ void BlockRandomizer::RetrieveDataChunks()
|
|||
// There could be some chunks in the m_chunks that are not required anymore, by swapping the chunks with m_chunks, we are removing those.
|
||||
std::map<size_t, ChunkPtr> chunks;
|
||||
size_t numLoadedChunks = m_chunks.size();
|
||||
|
||||
std::vector<bool> needed;
|
||||
needed.resize(randomizedEnd, false);
|
||||
|
||||
// Firstly, make sure we unload all not needed chunks:
|
||||
for (size_t i = 0; i < randomizedEnd; ++i)
|
||||
{
|
||||
auto const& chunk = window[i];
|
||||
|
@ -261,27 +263,36 @@ void BlockRandomizer::RetrieveDataChunks()
|
|||
continue;
|
||||
}
|
||||
|
||||
auto it = m_chunks.find(chunk.m_chunkId);
|
||||
auto it = m_chunks.find(chunk.m_original->m_id);
|
||||
if (it != m_chunks.end())
|
||||
{
|
||||
chunks[chunk.m_chunkId] = it->second;
|
||||
chunks[chunk.m_original->m_id] = it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
chunks[chunk.m_chunkId] = m_deserializer->GetChunk(chunk.m_original->m_id);
|
||||
|
||||
if (m_verbosity >= Information)
|
||||
fprintf(stderr, "BlockRandomizer::RetrieveDataChunks: paged in randomized chunk %u (original chunk: %u), now %" PRIu64 " chunks in memory\n",
|
||||
chunk.m_chunkId,
|
||||
chunk.m_original->m_id,
|
||||
++numLoadedChunks);
|
||||
needed[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Swapping current chunks in the m_chunks, by that removing all stale and remembering newly loaded.
|
||||
// Swapping current chunks in the m_chunks, by that removing all stale.
|
||||
// TODO diagnostics for paged out chunks?
|
||||
m_chunks.swap(chunks);
|
||||
|
||||
// Adding new ones.
|
||||
for (size_t i = 0; i < randomizedEnd; ++i)
|
||||
{
|
||||
if (needed[i])
|
||||
{
|
||||
auto const& chunk = window[i];
|
||||
m_chunks[chunk.m_original->m_id] = m_deserializer->GetChunk(chunk.m_original->m_id);
|
||||
if (m_verbosity >= Information)
|
||||
fprintf(stderr, "BlockRandomizer::RetrieveDataChunks: paged in randomized chunk %u (original chunk: %u), now %" PRIu64 " chunks in memory\n",
|
||||
chunk.m_chunkId,
|
||||
chunk.m_original->m_id,
|
||||
++numLoadedChunks);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_verbosity >= Notification)
|
||||
fprintf(stderr, "BlockRandomizer::RetrieveDataChunks: %" PRIu64 " chunks paged-in from chunk window [%u..%u]\n",
|
||||
m_chunks.size(),
|
||||
|
|
|
@ -107,7 +107,7 @@ private:
|
|||
// Exposed streams.
|
||||
std::vector<StreamDescriptionPtr> m_streams;
|
||||
|
||||
// A map of data chunks.
|
||||
// A map of data chunks from original chunk id into chunk.
|
||||
std::map<size_t, ChunkPtr> m_chunks;
|
||||
|
||||
// Last seen data chunk id.
|
||||
|
|
|
@ -191,21 +191,28 @@ namespace Microsoft { namespace MSR { namespace CNTK {
|
|||
size_t posBegin = m_randomizedChunks[chunkWindowBegin].m_sequencePositionStart;
|
||||
size_t posEnd = m_randomizedChunks[chunkWindowEnd - 1].SequenceEndPosition();
|
||||
|
||||
ChunkIdType tChunkIndex = GetChunkIndexForSequencePosition(t);
|
||||
auto& tSequence = GetRandomizedSequenceDescriptionByPosition(tChunkIndex, t);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// Pick a sequence position from [posBegin, posEnd)
|
||||
const size_t j = rand(posBegin, posEnd);
|
||||
|
||||
// Pick up j sequence.
|
||||
ChunkIdType jChunkIndex = GetChunkIndexForSequencePosition(j);
|
||||
auto& jSequence = GetRandomizedSequenceDescriptionByPosition(jChunkIndex, j);
|
||||
|
||||
// Try again if the sequence currently at j cannot be placed at position i.
|
||||
if (!IsValidForPosition(t, GetRandomizedSequenceDescriptionBySequenceId(j)))
|
||||
if (!IsValidForPosition(tChunkIndex, jSequence))
|
||||
continue;
|
||||
|
||||
// Try again if the sequence currently at i cannot be placed at position j.
|
||||
if (!IsValidForPosition(j, GetRandomizedSequenceDescriptionBySequenceId(t)))
|
||||
if (!IsValidForPosition(jChunkIndex, tSequence))
|
||||
continue;
|
||||
|
||||
// Swap and break out.
|
||||
std::swap(GetRandomizedSequenceDescriptionBySequenceId(t), GetRandomizedSequenceDescriptionBySequenceId(j)); // TODO old swap was perhaps more efficient
|
||||
std::swap(tSequence, jSequence);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +221,8 @@ namespace Microsoft { namespace MSR { namespace CNTK {
|
|||
for (size_t t = firstSequencePositionToRandomize; t < endSequencePosToRandomize; ++t)
|
||||
{
|
||||
// TODO assert only
|
||||
if (!IsValidForPosition(t, GetRandomizedSequenceDescriptionBySequenceId(t)))
|
||||
ChunkIdType tChunkIndex = GetChunkIndexForSequencePosition(t);
|
||||
if (!IsValidForPosition(tChunkIndex, GetRandomizedSequenceDescriptionByPosition(tChunkIndex, t)))
|
||||
{
|
||||
LogicError("SequenceRandomizer::RandomizeNextSequenceDescriptions: randomization logic mangled!");
|
||||
}
|
||||
|
@ -322,10 +330,10 @@ namespace Microsoft { namespace MSR { namespace CNTK {
|
|||
return m_currentSampleCursor;
|
||||
}
|
||||
|
||||
// Checks if the randomized sequence is valid for a target position using its chunk randomization window.
|
||||
bool SequenceRandomizer::IsValidForPosition(size_t targetPosition, const RandomizedSequenceDescription& seqDesc) const
|
||||
// Checks if the randomized sequence is valid for a target chunk.
|
||||
bool SequenceRandomizer::IsValidForPosition(ChunkIdType chunkIndex, const RandomizedSequenceDescription& seqDesc) const
|
||||
{
|
||||
const auto& chunk = m_randomizedChunks[GetChunkIndexForSequencePosition(targetPosition)];
|
||||
const auto& chunk = m_randomizedChunks[chunkIndex];
|
||||
return chunk.m_randomizationWindow.m_begin <= seqDesc.m_chunk->m_chunkId && seqDesc.m_chunk->m_chunkId < chunk.m_randomizationWindow.m_end;
|
||||
}
|
||||
|
||||
|
@ -365,11 +373,10 @@ namespace Microsoft { namespace MSR { namespace CNTK {
|
|||
m_chunkWindowEnd++;
|
||||
}
|
||||
|
||||
// Gets randomized sequence by the sequence id.
|
||||
RandomizedSequenceDescription& SequenceRandomizer::GetRandomizedSequenceDescriptionBySequenceId(size_t sequenceId)
|
||||
// Gets randomized sequence by the sequence position in the sweep and randomized chunk index.
|
||||
RandomizedSequenceDescription& SequenceRandomizer::GetRandomizedSequenceDescriptionByPosition(ChunkIdType chunkIndex, size_t sequenceSweepPosition)
|
||||
{
|
||||
ChunkIdType globalChunkIdx = GetChunkIndexForSequencePosition(sequenceId);
|
||||
size_t sequenceOffsetInsideChunk = sequenceId - m_randomizedChunks[globalChunkIdx].m_sequencePositionStart;
|
||||
return m_sequenceWindow[globalChunkIdx - m_chunkWindowBegin][sequenceOffsetInsideChunk];
|
||||
size_t sequenceOffsetInsideChunk = sequenceSweepPosition - m_randomizedChunks[chunkIndex].m_sequencePositionStart;
|
||||
return m_sequenceWindow[chunkIndex - m_chunkWindowBegin][sequenceOffsetInsideChunk];
|
||||
}
|
||||
}}}
|
||||
|
|
|
@ -19,10 +19,10 @@ struct RandomizedSequenceDescription
|
|||
{
|
||||
// Sequence id.
|
||||
size_t m_id;
|
||||
// Number of samples in sequence.
|
||||
uint32_t m_numberOfSamples;
|
||||
// Randomized chunk this sequence belongs to.
|
||||
const RandomizedChunk* m_chunk;
|
||||
// Number of samples in sequence.
|
||||
uint32_t m_numberOfSamples;
|
||||
};
|
||||
|
||||
// Class that given randomized chunks, randomizes sequence descriptions in a window of chunks.
|
||||
|
@ -64,14 +64,14 @@ private:
|
|||
// Randomize one more chunk if needed after the chunk cursor has been incremented.
|
||||
void RandomizeNextChunkIfNeeded();
|
||||
|
||||
// Checks if the randomized sequence is valid for a target position using its chunk randomization window.
|
||||
bool IsValidForPosition(size_t targetPosition, const RandomizedSequenceDescription& seqDesc) const;
|
||||
// Checks if the randomized sequence is valid for a target chunk.
|
||||
bool IsValidForPosition(ChunkIdType chunkIndex, const RandomizedSequenceDescription& seqDesc) const;
|
||||
|
||||
// Gets randomized chunk index using a sequence position in the sweep.
|
||||
ChunkIdType GetChunkIndexForSequencePosition(size_t sequencePosition) const;
|
||||
ChunkIdType GetChunkIndexForSequencePosition(size_t sequenceSweepPosition) const;
|
||||
|
||||
// Gets randomized sequence by the sequence id.
|
||||
RandomizedSequenceDescription& GetRandomizedSequenceDescriptionBySequenceId(size_t sequenceId);
|
||||
// Gets randomized sequence by sequence position in sweep and its randomized chunk index.
|
||||
RandomizedSequenceDescription& GetRandomizedSequenceDescriptionByPosition(ChunkIdType chunkIndex, size_t sequenceSweepPosition);
|
||||
|
||||
// Add randomizes sequences for the chunk with a given index.
|
||||
void AddRandomizedSequencesForChunk(ChunkIdType chunkIndex);
|
||||
|
|
|
@ -1,48 +1,48 @@
|
|||
=== Running /home/philly/jenkins/workspace/CNTK-Test-Linux-W1/build/gpu/debug/bin/cntk configFile=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Tests/EndToEndTests/Examples/Text/PennTreebank/RNN/../../../../../../Examples/Text/PennTreebank/Config/rnn.cntk currentDirectory=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Examples/Text/PennTreebank/Data RunDir=/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu DataDir=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Examples/Text/PennTreebank/Data ConfigDir=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Tests/EndToEndTests/Examples/Text/PennTreebank/RNN/../../../../../../Examples/Text/PennTreebank/Config OutputDir=/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu DeviceId=-1 timestamping=true initOnCPUOnly=true command=writeWordAndClassInfo:train:test train=[SGD=[maxEpochs=3]] train=[epochSize=2048]] test=[SGD=[maxEpochs=3]] train=[epochSize=2048]]
|
||||
=== Running /home/philly/jenkins/workspace/CNTK-Test-Linux-W1/build/gpu/release/bin/cntk configFile=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Tests/EndToEndTests/Examples/Text/PennTreebank/RNN/../../../../../../Examples/Text/PennTreebank/Config/rnn.cntk currentDirectory=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Examples/Text/PennTreebank/Data RunDir=/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu DataDir=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Examples/Text/PennTreebank/Data ConfigDir=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Tests/EndToEndTests/Examples/Text/PennTreebank/RNN/../../../../../../Examples/Text/PennTreebank/Config OutputDir=/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu DeviceId=-1 timestamping=true initOnCPUOnly=true command=writeWordAndClassInfo:train:test train=[SGD=[maxEpochs=3]] train=[epochSize=2048]] test=[SGD=[maxEpochs=3]] train=[epochSize=2048]]
|
||||
-------------------------------------------------------------------
|
||||
Build info:
|
||||
|
||||
Built time: May 5 2016 21:53:50
|
||||
Last modified date: Thu May 5 19:06:09 2016
|
||||
Build type: debug
|
||||
Built time: Jun 15 2016 08:10:22
|
||||
Last modified date: Wed Jun 15 08:04:52 2016
|
||||
Build type: release
|
||||
Build target: GPU
|
||||
With 1bit-SGD: no
|
||||
Math lib: acml
|
||||
Math lib: mkl
|
||||
CUDA_PATH: /usr/local/cuda-7.5
|
||||
CUB_PATH: /usr/local/cub-1.4.1
|
||||
CUDNN_PATH: /usr/local/cudnn-4.0
|
||||
Build Branch: HEAD
|
||||
Build SHA1: 163a49b07f300a0a2c74b074373431af0fc6959a
|
||||
Built by philly on cded08e6b560
|
||||
Build SHA1: 35cb5738e7ef794177a2fff06892a39700722dee
|
||||
Built by philly on d7142b6d43fb
|
||||
Build Path: /home/philly/jenkins/workspace/CNTK-Build-Linux
|
||||
-------------------------------------------------------------------
|
||||
Changed current directory to /home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Examples/Text/PennTreebank/Data
|
||||
05/05/2016 22:20:12: -------------------------------------------------------------------
|
||||
05/05/2016 22:20:12: Build info:
|
||||
06/16/2016 10:51:17: -------------------------------------------------------------------
|
||||
06/16/2016 10:51:17: Build info:
|
||||
|
||||
05/05/2016 22:20:12: Built time: May 5 2016 21:53:50
|
||||
05/05/2016 22:20:12: Last modified date: Thu May 5 19:06:09 2016
|
||||
05/05/2016 22:20:12: Build type: debug
|
||||
05/05/2016 22:20:12: Build target: GPU
|
||||
05/05/2016 22:20:12: With 1bit-SGD: no
|
||||
05/05/2016 22:20:12: Math lib: acml
|
||||
05/05/2016 22:20:12: CUDA_PATH: /usr/local/cuda-7.5
|
||||
05/05/2016 22:20:12: CUB_PATH: /usr/local/cub-1.4.1
|
||||
05/05/2016 22:20:12: CUDNN_PATH: /usr/local/cudnn-4.0
|
||||
05/05/2016 22:20:12: Build Branch: HEAD
|
||||
05/05/2016 22:20:12: Build SHA1: 163a49b07f300a0a2c74b074373431af0fc6959a
|
||||
05/05/2016 22:20:12: Built by philly on cded08e6b560
|
||||
05/05/2016 22:20:12: Build Path: /home/philly/jenkins/workspace/CNTK-Build-Linux
|
||||
05/05/2016 22:20:12: -------------------------------------------------------------------
|
||||
06/16/2016 10:51:17: Built time: Jun 15 2016 08:10:22
|
||||
06/16/2016 10:51:17: Last modified date: Wed Jun 15 08:04:52 2016
|
||||
06/16/2016 10:51:17: Build type: release
|
||||
06/16/2016 10:51:17: Build target: GPU
|
||||
06/16/2016 10:51:17: With 1bit-SGD: no
|
||||
06/16/2016 10:51:17: Math lib: mkl
|
||||
06/16/2016 10:51:17: CUDA_PATH: /usr/local/cuda-7.5
|
||||
06/16/2016 10:51:17: CUB_PATH: /usr/local/cub-1.4.1
|
||||
06/16/2016 10:51:17: CUDNN_PATH: /usr/local/cudnn-4.0
|
||||
06/16/2016 10:51:17: Build Branch: HEAD
|
||||
06/16/2016 10:51:17: Build SHA1: 35cb5738e7ef794177a2fff06892a39700722dee
|
||||
06/16/2016 10:51:17: Built by philly on d7142b6d43fb
|
||||
06/16/2016 10:51:17: Build Path: /home/philly/jenkins/workspace/CNTK-Build-Linux
|
||||
06/16/2016 10:51:17: -------------------------------------------------------------------
|
||||
|
||||
05/05/2016 22:20:12: Running on localhost at 2016/05/05 22:20:12
|
||||
05/05/2016 22:20:12: Command line:
|
||||
/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/build/gpu/debug/bin/cntk configFile=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Tests/EndToEndTests/Examples/Text/PennTreebank/RNN/../../../../../../Examples/Text/PennTreebank/Config/rnn.cntk currentDirectory=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Examples/Text/PennTreebank/Data RunDir=/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu DataDir=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Examples/Text/PennTreebank/Data ConfigDir=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Tests/EndToEndTests/Examples/Text/PennTreebank/RNN/../../../../../../Examples/Text/PennTreebank/Config OutputDir=/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu DeviceId=-1 timestamping=true initOnCPUOnly=true command=writeWordAndClassInfo:train:test train=[SGD=[maxEpochs=3]] train=[epochSize=2048]] test=[SGD=[maxEpochs=3]] train=[epochSize=2048]]
|
||||
06/16/2016 10:51:17: Running on localhost at 2016/06/16 10:51:17
|
||||
06/16/2016 10:51:17: Command line:
|
||||
/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/build/gpu/release/bin/cntk configFile=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Tests/EndToEndTests/Examples/Text/PennTreebank/RNN/../../../../../../Examples/Text/PennTreebank/Config/rnn.cntk currentDirectory=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Examples/Text/PennTreebank/Data RunDir=/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu DataDir=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Examples/Text/PennTreebank/Data ConfigDir=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Tests/EndToEndTests/Examples/Text/PennTreebank/RNN/../../../../../../Examples/Text/PennTreebank/Config OutputDir=/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu DeviceId=-1 timestamping=true initOnCPUOnly=true command=writeWordAndClassInfo:train:test train=[SGD=[maxEpochs=3]] train=[epochSize=2048]] test=[SGD=[maxEpochs=3]] train=[epochSize=2048]]
|
||||
|
||||
|
||||
|
||||
05/05/2016 22:20:12: >>>>>>>>>>>>>>>>>>>> RAW CONFIG (VARIABLES NOT RESOLVED) >>>>>>>>>>>>>>>>>>>>
|
||||
05/05/2016 22:20:12: RootDir = ".."
|
||||
06/16/2016 10:51:17: >>>>>>>>>>>>>>>>>>>> RAW CONFIG (VARIABLES NOT RESOLVED) >>>>>>>>>>>>>>>>>>>>
|
||||
06/16/2016 10:51:17: RootDir = ".."
|
||||
ConfigDir = "$RootDir$/Config"
|
||||
DataDir = "$RootDir$/Data"
|
||||
OutputDir = "$RootDir$/Output"
|
||||
|
@ -350,10 +350,10 @@ cacheBlockSize = 1
|
|||
]
|
||||
]
|
||||
currentDirectory=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Examples/Text/PennTreebank/Data
|
||||
RunDir=/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu
|
||||
RunDir=/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu
|
||||
DataDir=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Examples/Text/PennTreebank/Data
|
||||
ConfigDir=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Tests/EndToEndTests/Examples/Text/PennTreebank/RNN/../../../../../../Examples/Text/PennTreebank/Config
|
||||
OutputDir=/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu
|
||||
OutputDir=/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu
|
||||
DeviceId=-1
|
||||
timestamping=true
|
||||
initOnCPUOnly=true
|
||||
|
@ -363,19 +363,19 @@ train=[epochSize=2048]]
|
|||
test=[SGD=[maxEpochs=3]]
|
||||
train=[epochSize=2048]]
|
||||
|
||||
05/05/2016 22:20:12: <<<<<<<<<<<<<<<<<<<< RAW CONFIG (VARIABLES NOT RESOLVED) <<<<<<<<<<<<<<<<<<<<
|
||||
06/16/2016 10:51:17: <<<<<<<<<<<<<<<<<<<< RAW CONFIG (VARIABLES NOT RESOLVED) <<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
05/05/2016 22:20:12: >>>>>>>>>>>>>>>>>>>> RAW CONFIG WITH ALL VARIABLES RESOLVED >>>>>>>>>>>>>>>>>>>>
|
||||
05/05/2016 22:20:12: RootDir = ".."
|
||||
06/16/2016 10:51:17: >>>>>>>>>>>>>>>>>>>> RAW CONFIG WITH ALL VARIABLES RESOLVED >>>>>>>>>>>>>>>>>>>>
|
||||
06/16/2016 10:51:17: RootDir = ".."
|
||||
ConfigDir = "../Config"
|
||||
DataDir = "../Data"
|
||||
OutputDir = "../Output"
|
||||
ModelDir = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models"
|
||||
ModelDir = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models"
|
||||
deviceId = "auto"
|
||||
command = writeWordAndClassInfo:train:test:write
|
||||
precision = "float"
|
||||
traceLevel = 1
|
||||
modelPath = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/rnn.dnn"
|
||||
modelPath = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/rnn.dnn"
|
||||
numCPUThreads = 1
|
||||
confVocabSize = 10000
|
||||
confClassSize = 50
|
||||
|
@ -387,9 +387,9 @@ writeWordAndClassInfo = [
|
|||
inputFile = "/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Examples/Text/PennTreebank/Data/ptb.train.txt"
|
||||
beginSequence = "</s>"
|
||||
endSequence = "</s>"
|
||||
outputVocabFile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/vocab.txt"
|
||||
outputWord2Cls = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/word2cls.txt"
|
||||
outputCls2Index = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/cls2idx.txt"
|
||||
outputVocabFile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/vocab.txt"
|
||||
outputWord2Cls = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/word2cls.txt"
|
||||
outputCls2Index = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/cls2idx.txt"
|
||||
vocabSize = "10000"
|
||||
nbrClass = "50"
|
||||
cutoff = 0
|
||||
|
@ -443,8 +443,8 @@ lookupTableOrder = 1
|
|||
randomize = "none"
|
||||
nbruttsineachrecurrentiter = 0
|
||||
cacheBlockSize = 2000000
|
||||
wordclass = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/vocab.txt"
|
||||
wfile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sequenceSentence.bin"
|
||||
wordclass = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/vocab.txt"
|
||||
wfile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sequenceSentence.bin"
|
||||
wsize = 256
|
||||
wrecords = 1000
|
||||
windowSize = "10000"
|
||||
|
@ -459,7 +459,7 @@ cacheBlockSize = 2000000
|
|||
beginSequence = "</s>"
|
||||
endSequence = "</s>"
|
||||
labelDim = "10000"
|
||||
labelMappingFile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.txt"
|
||||
labelMappingFile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.txt"
|
||||
elementSize = 4
|
||||
sectionType = "labels"
|
||||
mapping = [
|
||||
|
@ -478,7 +478,7 @@ cacheBlockSize = 2000000
|
|||
beginSequence = "O"
|
||||
endSequence = "O"
|
||||
labelDim = "10000"
|
||||
labelMappingFile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.out.txt"
|
||||
labelMappingFile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.out.txt"
|
||||
elementSize = 4
|
||||
sectionType = "labels"
|
||||
mapping = [
|
||||
|
@ -497,8 +497,8 @@ cacheBlockSize = 2000000
|
|||
randomize = "none"
|
||||
nbruttsineachrecurrentiter = 0
|
||||
cacheBlockSize = 2000000
|
||||
wordclass = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/vocab.txt"
|
||||
wfile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sequenceSentence.valid.bin"
|
||||
wordclass = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/vocab.txt"
|
||||
wfile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sequenceSentence.valid.bin"
|
||||
wsize = 256
|
||||
wrecords = 1000
|
||||
windowSize = "10000"
|
||||
|
@ -510,7 +510,7 @@ cacheBlockSize = 2000000
|
|||
labelIn = [
|
||||
dim = 1
|
||||
labelDim = "10000"
|
||||
labelMappingFile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.out.txt"
|
||||
labelMappingFile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.out.txt"
|
||||
labelType = "Category"
|
||||
beginSequence = "</s>"
|
||||
endSequence = "</s>"
|
||||
|
@ -532,7 +532,7 @@ cacheBlockSize = 2000000
|
|||
beginSequence = "O"
|
||||
endSequence = "O"
|
||||
labelDim = "10000"
|
||||
labelMappingFile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.out.txt"
|
||||
labelMappingFile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.out.txt"
|
||||
elementSize = 4
|
||||
sectionType = "labels"
|
||||
mapping = [
|
||||
|
@ -557,8 +557,8 @@ minibatchSize = 8192
|
|||
randomize = "none"
|
||||
nbruttsineachrecurrentiter = 0
|
||||
cacheBlockSize = 2000000
|
||||
wordclass = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/vocab.txt"
|
||||
wfile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sequenceSentence.bin"
|
||||
wordclass = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/vocab.txt"
|
||||
wfile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sequenceSentence.bin"
|
||||
wsize = 256
|
||||
wrecords = 1000
|
||||
windowSize = "10000"
|
||||
|
@ -570,7 +570,7 @@ cacheBlockSize = 2000000
|
|||
labelIn = [
|
||||
dim = 1
|
||||
labelDim = "10000"
|
||||
labelMappingFile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.txt"
|
||||
labelMappingFile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.txt"
|
||||
labelType = "Category"
|
||||
beginSequence = "</s>"
|
||||
endSequence = "</s>"
|
||||
|
@ -592,7 +592,7 @@ cacheBlockSize = 2000000
|
|||
beginSequence = "O"
|
||||
endSequence = "O"
|
||||
labelDim = "10000"
|
||||
labelMappingFile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.out.txt"
|
||||
labelMappingFile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.out.txt"
|
||||
elementSize = 4
|
||||
sectionType = "labels"
|
||||
mapping = [
|
||||
|
@ -609,7 +609,7 @@ cacheBlockSize = 2000000
|
|||
]
|
||||
write = [
|
||||
action = "write"
|
||||
outputPath = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Write"
|
||||
outputPath = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Write"
|
||||
outputNodeNames = TrainNodeClassBasedCrossEntropy
|
||||
format = [
|
||||
sequencePrologue = "log P(W)="
|
||||
|
@ -623,8 +623,8 @@ minibatchSize = 8192
|
|||
randomize = "none"
|
||||
nbruttsineachrecurrentiter = 1
|
||||
cacheBlockSize = 1
|
||||
wordclass = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/vocab.txt"
|
||||
wfile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sequenceSentence.bin"
|
||||
wordclass = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/vocab.txt"
|
||||
wfile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sequenceSentence.bin"
|
||||
wsize = 256
|
||||
wrecords = 1000
|
||||
windowSize = "10000"
|
||||
|
@ -636,7 +636,7 @@ cacheBlockSize = 1
|
|||
labelIn = [
|
||||
dim = 1
|
||||
labelDim = "10000"
|
||||
labelMappingFile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.txt"
|
||||
labelMappingFile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.txt"
|
||||
labelType = "Category"
|
||||
beginSequence = "</s>"
|
||||
endSequence = "</s>"
|
||||
|
@ -658,7 +658,7 @@ cacheBlockSize = 1
|
|||
beginSequence = "O"
|
||||
endSequence = "O"
|
||||
labelDim = "10000"
|
||||
labelMappingFile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.out.txt"
|
||||
labelMappingFile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.out.txt"
|
||||
elementSize = 4
|
||||
sectionType = "labels"
|
||||
mapping = [
|
||||
|
@ -674,10 +674,10 @@ cacheBlockSize = 1
|
|||
]
|
||||
]
|
||||
currentDirectory=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Examples/Text/PennTreebank/Data
|
||||
RunDir=/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu
|
||||
RunDir=/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu
|
||||
DataDir=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Examples/Text/PennTreebank/Data
|
||||
ConfigDir=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Tests/EndToEndTests/Examples/Text/PennTreebank/RNN/../../../../../../Examples/Text/PennTreebank/Config
|
||||
OutputDir=/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu
|
||||
OutputDir=/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu
|
||||
DeviceId=-1
|
||||
timestamping=true
|
||||
initOnCPUOnly=true
|
||||
|
@ -687,9 +687,9 @@ train=[epochSize=2048]]
|
|||
test=[SGD=[maxEpochs=3]]
|
||||
train=[epochSize=2048]]
|
||||
|
||||
05/05/2016 22:20:12: <<<<<<<<<<<<<<<<<<<< RAW CONFIG WITH ALL VARIABLES RESOLVED <<<<<<<<<<<<<<<<<<<<
|
||||
06/16/2016 10:51:17: <<<<<<<<<<<<<<<<<<<< RAW CONFIG WITH ALL VARIABLES RESOLVED <<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
05/05/2016 22:20:12: >>>>>>>>>>>>>>>>>>>> PROCESSED CONFIG WITH ALL VARIABLES RESOLVED >>>>>>>>>>>>>>>>>>>>
|
||||
06/16/2016 10:51:17: >>>>>>>>>>>>>>>>>>>> PROCESSED CONFIG WITH ALL VARIABLES RESOLVED >>>>>>>>>>>>>>>>>>>>
|
||||
configparameters: rnn.cntk:]=true
|
||||
configparameters: rnn.cntk:command=writeWordAndClassInfo:train:test
|
||||
configparameters: rnn.cntk:confClassSize=50
|
||||
|
@ -699,13 +699,13 @@ configparameters: rnn.cntk:currentDirectory=/home/philly/jenkins/workspace/CNTK-
|
|||
configparameters: rnn.cntk:DataDir=/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Examples/Text/PennTreebank/Data
|
||||
configparameters: rnn.cntk:deviceId=-1
|
||||
configparameters: rnn.cntk:initOnCPUOnly=true
|
||||
configparameters: rnn.cntk:ModelDir=/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models
|
||||
configparameters: rnn.cntk:modelPath=/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/rnn.dnn
|
||||
configparameters: rnn.cntk:ModelDir=/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models
|
||||
configparameters: rnn.cntk:modelPath=/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/rnn.dnn
|
||||
configparameters: rnn.cntk:numCPUThreads=1
|
||||
configparameters: rnn.cntk:OutputDir=/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu
|
||||
configparameters: rnn.cntk:OutputDir=/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu
|
||||
configparameters: rnn.cntk:precision=float
|
||||
configparameters: rnn.cntk:RootDir=..
|
||||
configparameters: rnn.cntk:RunDir=/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu
|
||||
configparameters: rnn.cntk:RunDir=/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu
|
||||
configparameters: rnn.cntk:test=[
|
||||
action = "eval"
|
||||
minibatchSize = 8192
|
||||
|
@ -716,8 +716,8 @@ minibatchSize = 8192
|
|||
randomize = "none"
|
||||
nbruttsineachrecurrentiter = 0
|
||||
cacheBlockSize = 2000000
|
||||
wordclass = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/vocab.txt"
|
||||
wfile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sequenceSentence.bin"
|
||||
wordclass = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/vocab.txt"
|
||||
wfile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sequenceSentence.bin"
|
||||
wsize = 256
|
||||
wrecords = 1000
|
||||
windowSize = "10000"
|
||||
|
@ -729,7 +729,7 @@ cacheBlockSize = 2000000
|
|||
labelIn = [
|
||||
dim = 1
|
||||
labelDim = "10000"
|
||||
labelMappingFile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.txt"
|
||||
labelMappingFile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.txt"
|
||||
labelType = "Category"
|
||||
beginSequence = "</s>"
|
||||
endSequence = "</s>"
|
||||
|
@ -751,7 +751,7 @@ cacheBlockSize = 2000000
|
|||
beginSequence = "O"
|
||||
endSequence = "O"
|
||||
labelDim = "10000"
|
||||
labelMappingFile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.out.txt"
|
||||
labelMappingFile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.out.txt"
|
||||
elementSize = 4
|
||||
sectionType = "labels"
|
||||
mapping = [
|
||||
|
@ -818,8 +818,8 @@ lookupTableOrder = 1
|
|||
randomize = "none"
|
||||
nbruttsineachrecurrentiter = 0
|
||||
cacheBlockSize = 2000000
|
||||
wordclass = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/vocab.txt"
|
||||
wfile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sequenceSentence.bin"
|
||||
wordclass = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/vocab.txt"
|
||||
wfile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sequenceSentence.bin"
|
||||
wsize = 256
|
||||
wrecords = 1000
|
||||
windowSize = "10000"
|
||||
|
@ -834,7 +834,7 @@ cacheBlockSize = 2000000
|
|||
beginSequence = "</s>"
|
||||
endSequence = "</s>"
|
||||
labelDim = "10000"
|
||||
labelMappingFile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.txt"
|
||||
labelMappingFile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.txt"
|
||||
elementSize = 4
|
||||
sectionType = "labels"
|
||||
mapping = [
|
||||
|
@ -853,7 +853,7 @@ cacheBlockSize = 2000000
|
|||
beginSequence = "O"
|
||||
endSequence = "O"
|
||||
labelDim = "10000"
|
||||
labelMappingFile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.out.txt"
|
||||
labelMappingFile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.out.txt"
|
||||
elementSize = 4
|
||||
sectionType = "labels"
|
||||
mapping = [
|
||||
|
@ -872,8 +872,8 @@ cacheBlockSize = 2000000
|
|||
randomize = "none"
|
||||
nbruttsineachrecurrentiter = 0
|
||||
cacheBlockSize = 2000000
|
||||
wordclass = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/vocab.txt"
|
||||
wfile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sequenceSentence.valid.bin"
|
||||
wordclass = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/vocab.txt"
|
||||
wfile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sequenceSentence.valid.bin"
|
||||
wsize = 256
|
||||
wrecords = 1000
|
||||
windowSize = "10000"
|
||||
|
@ -885,7 +885,7 @@ cacheBlockSize = 2000000
|
|||
labelIn = [
|
||||
dim = 1
|
||||
labelDim = "10000"
|
||||
labelMappingFile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.out.txt"
|
||||
labelMappingFile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.out.txt"
|
||||
labelType = "Category"
|
||||
beginSequence = "</s>"
|
||||
endSequence = "</s>"
|
||||
|
@ -907,7 +907,7 @@ cacheBlockSize = 2000000
|
|||
beginSequence = "O"
|
||||
endSequence = "O"
|
||||
labelDim = "10000"
|
||||
labelMappingFile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.out.txt"
|
||||
labelMappingFile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.out.txt"
|
||||
elementSize = 4
|
||||
sectionType = "labels"
|
||||
mapping = [
|
||||
|
@ -927,7 +927,7 @@ configparameters: rnn.cntk:trainFile=ptb.train.txt
|
|||
configparameters: rnn.cntk:validFile=ptb.valid.txt
|
||||
configparameters: rnn.cntk:write=[
|
||||
action = "write"
|
||||
outputPath = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Write"
|
||||
outputPath = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Write"
|
||||
outputNodeNames = TrainNodeClassBasedCrossEntropy
|
||||
format = [
|
||||
sequencePrologue = "log P(W)="
|
||||
|
@ -941,8 +941,8 @@ minibatchSize = 8192
|
|||
randomize = "none"
|
||||
nbruttsineachrecurrentiter = 1
|
||||
cacheBlockSize = 1
|
||||
wordclass = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/vocab.txt"
|
||||
wfile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sequenceSentence.bin"
|
||||
wordclass = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/vocab.txt"
|
||||
wfile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sequenceSentence.bin"
|
||||
wsize = 256
|
||||
wrecords = 1000
|
||||
windowSize = "10000"
|
||||
|
@ -954,7 +954,7 @@ cacheBlockSize = 1
|
|||
labelIn = [
|
||||
dim = 1
|
||||
labelDim = "10000"
|
||||
labelMappingFile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.txt"
|
||||
labelMappingFile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.txt"
|
||||
labelType = "Category"
|
||||
beginSequence = "</s>"
|
||||
endSequence = "</s>"
|
||||
|
@ -976,7 +976,7 @@ cacheBlockSize = 1
|
|||
beginSequence = "O"
|
||||
endSequence = "O"
|
||||
labelDim = "10000"
|
||||
labelMappingFile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.out.txt"
|
||||
labelMappingFile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.out.txt"
|
||||
elementSize = 4
|
||||
sectionType = "labels"
|
||||
mapping = [
|
||||
|
@ -997,32 +997,32 @@ configparameters: rnn.cntk:writeWordAndClassInfo=[
|
|||
inputFile = "/home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Examples/Text/PennTreebank/Data/ptb.train.txt"
|
||||
beginSequence = "</s>"
|
||||
endSequence = "</s>"
|
||||
outputVocabFile = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/vocab.txt"
|
||||
outputWord2Cls = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/word2cls.txt"
|
||||
outputCls2Index = "/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/cls2idx.txt"
|
||||
outputVocabFile = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/vocab.txt"
|
||||
outputWord2Cls = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/word2cls.txt"
|
||||
outputCls2Index = "/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/cls2idx.txt"
|
||||
vocabSize = "10000"
|
||||
nbrClass = "50"
|
||||
cutoff = 0
|
||||
printValues = true
|
||||
]
|
||||
|
||||
05/05/2016 22:20:12: <<<<<<<<<<<<<<<<<<<< PROCESSED CONFIG WITH ALL VARIABLES RESOLVED <<<<<<<<<<<<<<<<<<<<
|
||||
05/05/2016 22:20:12: Commands: writeWordAndClassInfo train test
|
||||
05/05/2016 22:20:12: Precision = "float"
|
||||
05/05/2016 22:20:12: Using 1 CPU threads.
|
||||
05/05/2016 22:20:12: CNTKModelPath: /tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/rnn.dnn
|
||||
05/05/2016 22:20:12: CNTKCommandTrainInfo: train : 3
|
||||
05/05/2016 22:20:12: CNTKCommandTrainInfo: CNTKNoMoreCommands_Total : 3
|
||||
06/16/2016 10:51:17: <<<<<<<<<<<<<<<<<<<< PROCESSED CONFIG WITH ALL VARIABLES RESOLVED <<<<<<<<<<<<<<<<<<<<
|
||||
06/16/2016 10:51:17: Commands: writeWordAndClassInfo train test
|
||||
06/16/2016 10:51:17: Precision = "float"
|
||||
06/16/2016 10:51:17: Using 1 CPU threads.
|
||||
06/16/2016 10:51:17: CNTKModelPath: /tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/rnn.dnn
|
||||
06/16/2016 10:51:17: CNTKCommandTrainInfo: train : 3
|
||||
06/16/2016 10:51:17: CNTKCommandTrainInfo: CNTKNoMoreCommands_Total : 3
|
||||
|
||||
05/05/2016 22:20:12: ##############################################################################
|
||||
05/05/2016 22:20:12: # #
|
||||
05/05/2016 22:20:12: # Action "writeWordAndClass" #
|
||||
05/05/2016 22:20:12: # #
|
||||
05/05/2016 22:20:12: ##############################################################################
|
||||
06/16/2016 10:51:17: ##############################################################################
|
||||
06/16/2016 10:51:17: # #
|
||||
06/16/2016 10:51:17: # Action "writeWordAndClass" #
|
||||
06/16/2016 10:51:17: # #
|
||||
06/16/2016 10:51:17: ##############################################################################
|
||||
|
||||
Vocabulary file --> /tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/vocab.txt
|
||||
Word-to-class map --> /tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/word2cls.txt
|
||||
Class-to-index map --> /tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/cls2idx.txt
|
||||
Vocabulary file --> /tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/vocab.txt
|
||||
Word-to-class map --> /tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/word2cls.txt
|
||||
Class-to-index map --> /tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/cls2idx.txt
|
||||
|
||||
Reading input file inputFile: /home/philly/jenkins/workspace/CNTK-Test-Linux-W1/Examples/Text/PennTreebank/Data/ptb.train.txt
|
||||
Vocabulary size 10000.
|
||||
|
@ -1030,23 +1030,23 @@ Created vocabulary file with 10000 entries.
|
|||
Created word-to-class map with 10000 entries.
|
||||
Created class-to-index map with 50 entries.
|
||||
|
||||
05/05/2016 22:20:12: Action "writeWordAndClass" complete.
|
||||
06/16/2016 10:51:17: Action "writeWordAndClass" complete.
|
||||
|
||||
|
||||
05/05/2016 22:20:12: ##############################################################################
|
||||
05/05/2016 22:20:12: # #
|
||||
05/05/2016 22:20:12: # Action "train" #
|
||||
05/05/2016 22:20:12: # #
|
||||
05/05/2016 22:20:12: ##############################################################################
|
||||
06/16/2016 10:51:17: ##############################################################################
|
||||
06/16/2016 10:51:17: # #
|
||||
06/16/2016 10:51:17: # Action "train" #
|
||||
06/16/2016 10:51:17: # #
|
||||
06/16/2016 10:51:17: ##############################################################################
|
||||
|
||||
05/05/2016 22:20:12: CNTKCommandTrainBegin: train
|
||||
06/16/2016 10:51:17: CNTKCommandTrainBegin: train
|
||||
SimpleNetworkBuilder Using CPU
|
||||
LMSequenceReader: Label mapping will be created internally on the fly because the labelMappingFile was not found: /tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.txt
|
||||
LMSequenceReader: Label mapping will be created internally on the fly because the labelMappingFile was not found: /tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.out.txt
|
||||
LMSequenceReader: Label mapping will be created internally on the fly because the labelMappingFile was not found: /tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.out.txt
|
||||
LMSequenceReader: Label mapping will be created internally on the fly because the labelMappingFile was not found: /tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.out.txt
|
||||
LMSequenceReader: Label mapping will be created internally on the fly because the labelMappingFile was not found: /tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.txt
|
||||
LMSequenceReader: Label mapping will be created internally on the fly because the labelMappingFile was not found: /tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.out.txt
|
||||
LMSequenceReader: Label mapping will be created internally on the fly because the labelMappingFile was not found: /tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.out.txt
|
||||
LMSequenceReader: Label mapping will be created internally on the fly because the labelMappingFile was not found: /tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.out.txt
|
||||
|
||||
05/05/2016 22:20:13: Creating virgin network.
|
||||
06/16/2016 10:51:17: Creating virgin network.
|
||||
|
||||
Post-processing network...
|
||||
|
||||
|
@ -1156,10 +1156,10 @@ Validating network, final pass.
|
|||
|
||||
Post-processing network complete.
|
||||
|
||||
05/05/2016 22:20:13: Created model with 63 nodes on CPU.
|
||||
06/16/2016 10:51:17: Created model with 63 nodes on CPU.
|
||||
|
||||
05/05/2016 22:20:13: Training criterion node(s):
|
||||
05/05/2016 22:20:13: TrainNodeClassBasedCrossEntropy = ClassBasedCrossEntropyWithSoftmax
|
||||
06/16/2016 10:51:17: Training criterion node(s):
|
||||
06/16/2016 10:51:17: TrainNodeClassBasedCrossEntropy = ClassBasedCrossEntropyWithSoftmax
|
||||
|
||||
|
||||
Allocating matrices for forward and/or backward propagation.
|
||||
|
@ -1167,187 +1167,187 @@ Allocating matrices for forward and/or backward propagation.
|
|||
Memory Sharing Structure:
|
||||
|
||||
(nil): {[PosteriorProb Gradient[10000 x 1 x *]] [PosteriorProb Value[10000 x 1 x *]] [features Gradient[10000 x *]] [labels Gradient[4 x *]] [outputs Gradient[10000 x 1 x *]] }
|
||||
0x2debf88: {[WXC0 Value[200 x 150]] }
|
||||
0x2dec998: {[E0 Value[150 x 10000]] }
|
||||
0x2dee658: {[features Value[10000 x *]] }
|
||||
0x2def538: {[bf0 Value[200 x 1]] }
|
||||
0x2defac8: {[WXF0 Value[200 x 150]] }
|
||||
0x2df40f8: {[WCI0 Value[200 x 1]] }
|
||||
0x2e08d38: {[WHI0 Value[200 x 200]] }
|
||||
0x2e09858: {[WXI0 Value[200 x 150]] }
|
||||
0x2e09bb8: {[WXO0 Value[200 x 150]] }
|
||||
0x341fbe8: {[bo0 Value[200 x 1]] }
|
||||
0x341ffd8: {[bi0 Value[200 x 1]] }
|
||||
0x3420708: {[bc0 Value[200 x 1]] }
|
||||
0x3420888: {[WHF0 Value[200 x 200]] }
|
||||
0x3a2b938: {[WCF0 Value[200 x 1]] }
|
||||
0x3a2c108: {[WHO0 Value[200 x 200]] }
|
||||
0x3a2c5a8: {[WCO0 Value[200 x 1]] }
|
||||
0x3a2cd78: {[WHC0 Value[200 x 200]] }
|
||||
0x3a2d418: {[AutoName0 Value[200 x 1 x *]] }
|
||||
0x3a2db78: {[AutoName1 Value[200 x 1 x *]] }
|
||||
0x3a2e1c8: {[AutoName2 Value[200 x 1 x *]] [WXC0 Gradient[200 x 150]] }
|
||||
0x3a2e818: {[AutoName3 Value[200 x 1 x *]] }
|
||||
0x3a2ef78: {[AutoName4 Value[200 x 1 x *]] }
|
||||
0x3a2f5c8: {[AutoName5 Value[200 x 1 x *]] }
|
||||
0x3a2fc18: {[AutoName6 Value[200 x 1 x *]] }
|
||||
0x3ac85b8: {[W2 Value[200 x 10000]] }
|
||||
0x3ac8a38: {[labels Value[4 x *]] }
|
||||
0x3ac8f18: {[WeightForClassPostProb Value[50 x 200]] }
|
||||
0x3ad5c78: {[outputs Value[10000 x 1 x *]] }
|
||||
0x3ad7398: {[TrainNodeClassBasedCrossEntropy Value[1]] }
|
||||
0x3aded18: {[LookupTable Value[150 x *]] }
|
||||
0x3adf0b8: {[AutoName31 Value[200 x *]] [E0 Gradient[150 x 10000]] }
|
||||
0x3adf928: {[AutoName22 Value[200 x *]] [AutoName31 Gradient[200 x *]] }
|
||||
0x3adfae8: {[AutoName23 Value[200 x 1 x *]] [WXF0 Gradient[200 x 150]] }
|
||||
0x3adfbe8: {[AutoName22 Gradient[200 x *]] [AutoName9 Value[200 x *]] [bo0 Gradient[200 x 1]] }
|
||||
0x3ae01c8: {[AutoName32 Value[200 x 1 x *]] [WXO0 Gradient[200 x 150]] }
|
||||
0x3ae09c8: {[AutoName10 Value[200 x 1 x *]] [WXI0 Gradient[200 x 150]] }
|
||||
0x3ae0b88: {[AutoName16 Value[200 x *]] [AutoName9 Gradient[200 x *]] [bf0 Gradient[200 x 1]] }
|
||||
0x3ae0d48: {[AutoName30 Value[200 x 1 x *]] }
|
||||
0x3ae0f08: {[AutoName33 Value[200 x 1 x *]] }
|
||||
0x3ae10c8: {[AutoName21 Value[200 x 1 x *]] }
|
||||
0x3ae1288: {[AutoName24 Value[200 x 1 x *]] }
|
||||
0x3ae1448: {[AutoName20 Value[200 x 1 x *]] }
|
||||
0x3ae1608: {[AutoName25 Value[200 x 1 x *]] }
|
||||
0x3ae17c8: {[AutoName26 Value[200 x 1 x *]] }
|
||||
0x3ae1988: {[AutoName27 Value[200 x 1 x *]] }
|
||||
0x3ae1b48: {[AutoName8 Value[200 x 1 x *]] }
|
||||
0x3ae1d08: {[AutoName11 Value[200 x 1 x *]] }
|
||||
0x3ae1ec8: {[AutoName7 Value[200 x 1 x *]] }
|
||||
0x3ae2088: {[AutoName12 Value[200 x 1 x *]] }
|
||||
0x3ae2248: {[AutoName13 Value[200 x 1 x *]] }
|
||||
0x3ae2408: {[AutoName14 Value[200 x 1 x *]] }
|
||||
0x3ae25c8: {[AutoName15 Value[200 x 1 x *]] }
|
||||
0x3ae2788: {[AutoName17 Value[200 x 1 x *]] }
|
||||
0x3ae2948: {[AutoName18 Value[200 x 1 x *]] }
|
||||
0x3ae2b08: {[AutoName19 Value[200 x 1 x *]] }
|
||||
0x3ae2cc8: {[AutoName28 Value[200 x 1 x *]] }
|
||||
0x3ae2e88: {[AutoName29 Value[200 x 1 x *]] }
|
||||
0x3ae3048: {[AutoName34 Value[200 x 1 x *]] }
|
||||
0x3ae3208: {[AutoName35 Value[200 x 1 x *]] }
|
||||
0x3ae33c8: {[AutoName36 Value[200 x 1 x *]] }
|
||||
0x3ae3588: {[AutoName37 Value[200 x 1 x *]] }
|
||||
0x3ae3748: {[AutoName35 Gradient[200 x 1 x *]] [ClassPostProb Value[50 x 1 x *]] }
|
||||
0x3ae3908: {[TrainNodeClassBasedCrossEntropy Gradient[1]] }
|
||||
0x3ae3ac8: {[AutoName37 Gradient[200 x 1 x *]] }
|
||||
0x3ae3c88: {[W2 Gradient[200 x 10000]] }
|
||||
0x3ae3e48: {[AutoName36 Gradient[200 x 1 x *]] [ClassPostProb Gradient[50 x 1 x *]] }
|
||||
0x3ae4008: {[WeightForClassPostProb Gradient[50 x 200]] }
|
||||
0x3ae41c8: {[AutoName28 Gradient[200 x 1 x *]] }
|
||||
0x3ae4388: {[AutoName34 Gradient[200 x 1 x *]] }
|
||||
0x3ae4548: {[AutoName33 Gradient[200 x 1 x *]] }
|
||||
0x3ae4708: {[AutoName29 Gradient[200 x 1 x *]] }
|
||||
0x3ae4c48: {[WCO0 Gradient[200 x 1]] }
|
||||
0x3ae4e08: {[AutoName27 Gradient[200 x 1 x *]] }
|
||||
0x3ae4fc8: {[AutoName19 Gradient[200 x 1 x *]] }
|
||||
0x3ae5188: {[AutoName13 Gradient[200 x 1 x *]] }
|
||||
0x3ae5348: {[AutoName18 Gradient[200 x 1 x *]] }
|
||||
0x3ae5508: {[AutoName17 Gradient[200 x 1 x *]] }
|
||||
0x3ae56c8: {[AutoName16 Gradient[200 x *]] [bi0 Gradient[200 x 1]] }
|
||||
0x3ae5888: {[AutoName15 Gradient[200 x 1 x *]] }
|
||||
0x3ae5a48: {[AutoName14 Gradient[200 x 1 x *]] }
|
||||
0x3ae5c08: {[bc0 Gradient[200 x 1]] }
|
||||
0x3ae5dc8: {[WHC0 Gradient[200 x 200]] }
|
||||
0x3ae5f88: {[AutoName3 Gradient[200 x 1 x *]] }
|
||||
0x3ae6148: {[AutoName12 Gradient[200 x 1 x *]] }
|
||||
0x3ae6308: {[AutoName11 Gradient[200 x 1 x *]] }
|
||||
0x3ae64c8: {[AutoName7 Gradient[200 x 1 x *]] }
|
||||
0x3ae6a08: {[WCI0 Gradient[200 x 1]] }
|
||||
0x3ae6bc8: {[AutoName4 Gradient[200 x 1 x *]] }
|
||||
0x3ae6d88: {[AutoName10 Gradient[200 x 1 x *]] }
|
||||
0x3ae6f48: {[AutoName8 Gradient[200 x 1 x *]] }
|
||||
0x3ae7108: {[WHI0 Gradient[200 x 200]] }
|
||||
0x3ae72c8: {[AutoName0 Gradient[200 x 1 x *]] }
|
||||
0x3ae7488: {[AutoName26 Gradient[200 x 1 x *]] }
|
||||
0x3ae7648: {[AutoName6 Gradient[200 x 1 x *]] }
|
||||
0x3ae7808: {[AutoName25 Gradient[200 x 1 x *]] }
|
||||
0x3ae79c8: {[AutoName24 Gradient[200 x 1 x *]] }
|
||||
0x3ae7b88: {[AutoName20 Gradient[200 x 1 x *]] }
|
||||
0x3ae80c8: {[WCF0 Gradient[200 x 1]] }
|
||||
0x3ae8288: {[AutoName5 Gradient[200 x 1 x *]] }
|
||||
0x3ae8448: {[AutoName23 Gradient[200 x 1 x *]] }
|
||||
0x3ae8608: {[AutoName21 Gradient[200 x 1 x *]] }
|
||||
0x3ae87c8: {[WHF0 Gradient[200 x 200]] }
|
||||
0x3ae8988: {[AutoName1 Gradient[200 x 1 x *]] }
|
||||
0x3ae8b48: {[AutoName32 Gradient[200 x 1 x *]] }
|
||||
0x3ae8d08: {[AutoName30 Gradient[200 x 1 x *]] }
|
||||
0x3ae8ec8: {[WHO0 Gradient[200 x 200]] }
|
||||
0x3ae9088: {[AutoName2 Gradient[200 x 1 x *]] [LookupTable Gradient[150 x *]] }
|
||||
0x2198e68: {[E0 Value[150 x 10000]] }
|
||||
0x219a888: {[WHI0 Value[200 x 200]] }
|
||||
0x219c018: {[WXC0 Value[200 x 150]] }
|
||||
0x219dd48: {[bc0 Value[200 x 1]] }
|
||||
0x219e0c8: {[features Value[10000 x *]] }
|
||||
0x21b14a8: {[WXO0 Value[200 x 150]] }
|
||||
0x21b1fb8: {[bo0 Value[200 x 1]] }
|
||||
0x27c7b88: {[bi0 Value[200 x 1]] }
|
||||
0x27c8188: {[WXF0 Value[200 x 150]] }
|
||||
0x27c8688: {[WXI0 Value[200 x 150]] }
|
||||
0x27c8798: {[bf0 Value[200 x 1]] }
|
||||
0x2dd2d88: {[WCI0 Value[200 x 1]] }
|
||||
0x2dd34d8: {[WHF0 Value[200 x 200]] }
|
||||
0x2dd3978: {[WCF0 Value[200 x 1]] }
|
||||
0x2dd4148: {[WHO0 Value[200 x 200]] }
|
||||
0x2dd45e8: {[WCO0 Value[200 x 1]] }
|
||||
0x2dd4db8: {[WHC0 Value[200 x 200]] }
|
||||
0x2dd5458: {[AutoName0 Value[200 x 1 x *]] }
|
||||
0x2dd5bb8: {[AutoName1 Value[200 x 1 x *]] }
|
||||
0x2dd6208: {[AutoName2 Value[200 x 1 x *]] [WXC0 Gradient[200 x 150]] }
|
||||
0x2dd6858: {[AutoName3 Value[200 x 1 x *]] }
|
||||
0x2dd6fb8: {[AutoName4 Value[200 x 1 x *]] }
|
||||
0x2dd7608: {[AutoName5 Value[200 x 1 x *]] }
|
||||
0x2dd7c58: {[AutoName6 Value[200 x 1 x *]] }
|
||||
0x2e70588: {[W2 Value[200 x 10000]] }
|
||||
0x2e70a08: {[labels Value[4 x *]] }
|
||||
0x2e70ee8: {[WeightForClassPostProb Value[50 x 200]] }
|
||||
0x2e7da38: {[outputs Value[10000 x 1 x *]] }
|
||||
0x2e7f988: {[TrainNodeClassBasedCrossEntropy Value[1]] }
|
||||
0x2e86e38: {[LookupTable Value[150 x *]] }
|
||||
0x2e871d8: {[AutoName31 Value[200 x *]] [E0 Gradient[150 x 10000]] }
|
||||
0x2e87a48: {[AutoName22 Value[200 x *]] [AutoName31 Gradient[200 x *]] }
|
||||
0x2e87c08: {[AutoName23 Value[200 x 1 x *]] [WXF0 Gradient[200 x 150]] }
|
||||
0x2e87d08: {[AutoName22 Gradient[200 x *]] [AutoName9 Value[200 x *]] [bo0 Gradient[200 x 1]] }
|
||||
0x2e882e8: {[AutoName32 Value[200 x 1 x *]] [WXO0 Gradient[200 x 150]] }
|
||||
0x2e88a88: {[AutoName10 Value[200 x 1 x *]] [WXI0 Gradient[200 x 150]] }
|
||||
0x2e88c48: {[AutoName16 Value[200 x *]] [AutoName9 Gradient[200 x *]] [bf0 Gradient[200 x 1]] }
|
||||
0x2e88e08: {[AutoName30 Value[200 x 1 x *]] }
|
||||
0x2e88fc8: {[AutoName33 Value[200 x 1 x *]] }
|
||||
0x2e89188: {[AutoName21 Value[200 x 1 x *]] }
|
||||
0x2e89348: {[AutoName24 Value[200 x 1 x *]] }
|
||||
0x2e89508: {[AutoName20 Value[200 x 1 x *]] }
|
||||
0x2e896c8: {[AutoName25 Value[200 x 1 x *]] }
|
||||
0x2e89888: {[AutoName26 Value[200 x 1 x *]] }
|
||||
0x2e89a48: {[AutoName27 Value[200 x 1 x *]] }
|
||||
0x2e89c08: {[AutoName8 Value[200 x 1 x *]] }
|
||||
0x2e89dc8: {[AutoName11 Value[200 x 1 x *]] }
|
||||
0x2e89f88: {[AutoName7 Value[200 x 1 x *]] }
|
||||
0x2e8a148: {[AutoName12 Value[200 x 1 x *]] }
|
||||
0x2e8a308: {[AutoName13 Value[200 x 1 x *]] }
|
||||
0x2e8a4c8: {[AutoName14 Value[200 x 1 x *]] }
|
||||
0x2e8a688: {[AutoName15 Value[200 x 1 x *]] }
|
||||
0x2e8a848: {[AutoName17 Value[200 x 1 x *]] }
|
||||
0x2e8aa08: {[AutoName18 Value[200 x 1 x *]] }
|
||||
0x2e8abc8: {[AutoName19 Value[200 x 1 x *]] }
|
||||
0x2e8ad88: {[AutoName28 Value[200 x 1 x *]] }
|
||||
0x2e8af48: {[AutoName29 Value[200 x 1 x *]] }
|
||||
0x2e8b108: {[AutoName34 Value[200 x 1 x *]] }
|
||||
0x2e8b2c8: {[AutoName35 Value[200 x 1 x *]] }
|
||||
0x2e8b488: {[AutoName36 Value[200 x 1 x *]] }
|
||||
0x2e8b648: {[AutoName37 Value[200 x 1 x *]] }
|
||||
0x2e8b808: {[AutoName35 Gradient[200 x 1 x *]] [ClassPostProb Value[50 x 1 x *]] }
|
||||
0x2e8b9c8: {[TrainNodeClassBasedCrossEntropy Gradient[1]] }
|
||||
0x2e8bb88: {[AutoName37 Gradient[200 x 1 x *]] }
|
||||
0x2e8bd48: {[W2 Gradient[200 x 10000]] }
|
||||
0x2e8bf08: {[AutoName36 Gradient[200 x 1 x *]] [ClassPostProb Gradient[50 x 1 x *]] }
|
||||
0x2e8c0c8: {[WeightForClassPostProb Gradient[50 x 200]] }
|
||||
0x2e8c288: {[AutoName28 Gradient[200 x 1 x *]] }
|
||||
0x2e8c448: {[AutoName34 Gradient[200 x 1 x *]] }
|
||||
0x2e8c608: {[AutoName33 Gradient[200 x 1 x *]] }
|
||||
0x2e8c7c8: {[AutoName29 Gradient[200 x 1 x *]] }
|
||||
0x2e8cd08: {[WCO0 Gradient[200 x 1]] }
|
||||
0x2e8cec8: {[AutoName27 Gradient[200 x 1 x *]] }
|
||||
0x2e8d088: {[AutoName19 Gradient[200 x 1 x *]] }
|
||||
0x2e8d248: {[AutoName13 Gradient[200 x 1 x *]] }
|
||||
0x2e8d408: {[AutoName18 Gradient[200 x 1 x *]] }
|
||||
0x2e8d5c8: {[AutoName17 Gradient[200 x 1 x *]] }
|
||||
0x2e8d788: {[AutoName16 Gradient[200 x *]] [bi0 Gradient[200 x 1]] }
|
||||
0x2e8d948: {[AutoName15 Gradient[200 x 1 x *]] }
|
||||
0x2e8db08: {[AutoName14 Gradient[200 x 1 x *]] }
|
||||
0x2e8dcc8: {[bc0 Gradient[200 x 1]] }
|
||||
0x2e8de88: {[WHC0 Gradient[200 x 200]] }
|
||||
0x2e8e048: {[AutoName3 Gradient[200 x 1 x *]] }
|
||||
0x2e8e208: {[AutoName12 Gradient[200 x 1 x *]] }
|
||||
0x2e8e3c8: {[AutoName11 Gradient[200 x 1 x *]] }
|
||||
0x2e8e588: {[AutoName7 Gradient[200 x 1 x *]] }
|
||||
0x2e8eac8: {[WCI0 Gradient[200 x 1]] }
|
||||
0x2e8ec88: {[AutoName4 Gradient[200 x 1 x *]] }
|
||||
0x2e8ee48: {[AutoName10 Gradient[200 x 1 x *]] }
|
||||
0x2e8f008: {[AutoName8 Gradient[200 x 1 x *]] }
|
||||
0x2e8f1c8: {[WHI0 Gradient[200 x 200]] }
|
||||
0x2e8f388: {[AutoName0 Gradient[200 x 1 x *]] }
|
||||
0x2e8f548: {[AutoName26 Gradient[200 x 1 x *]] }
|
||||
0x2e8f708: {[AutoName6 Gradient[200 x 1 x *]] }
|
||||
0x2e8f8c8: {[AutoName25 Gradient[200 x 1 x *]] }
|
||||
0x2e8fa88: {[AutoName24 Gradient[200 x 1 x *]] }
|
||||
0x2e8fc48: {[AutoName20 Gradient[200 x 1 x *]] }
|
||||
0x2e90188: {[WCF0 Gradient[200 x 1]] }
|
||||
0x2e90348: {[AutoName5 Gradient[200 x 1 x *]] }
|
||||
0x2e90508: {[AutoName23 Gradient[200 x 1 x *]] }
|
||||
0x2e906c8: {[AutoName21 Gradient[200 x 1 x *]] }
|
||||
0x2e90888: {[WHF0 Gradient[200 x 200]] }
|
||||
0x2e90a48: {[AutoName1 Gradient[200 x 1 x *]] }
|
||||
0x2e90c08: {[AutoName32 Gradient[200 x 1 x *]] }
|
||||
0x2e90dc8: {[AutoName30 Gradient[200 x 1 x *]] }
|
||||
0x2e90f88: {[WHO0 Gradient[200 x 200]] }
|
||||
0x2e91148: {[AutoName2 Gradient[200 x 1 x *]] [LookupTable Gradient[150 x *]] }
|
||||
|
||||
05/05/2016 22:20:13: No PreCompute nodes found, skipping PreCompute step.
|
||||
06/16/2016 10:51:17: No PreCompute nodes found, skipping PreCompute step.
|
||||
|
||||
05/05/2016 22:20:14: Starting Epoch 1: learning rate per sample = 0.100000 effective momentum = 0.000000 momentum as time constant = 0.0 samples
|
||||
06/16/2016 10:51:17: Starting Epoch 1: learning rate per sample = 0.100000 effective momentum = 0.000000 momentum as time constant = 0.0 samples
|
||||
|
||||
05/05/2016 22:20:14: Starting minibatch loop.
|
||||
06/16/2016 10:51:17: Starting minibatch loop.
|
||||
LMSequenceReader: Reading epoch data... 42068 sequences read.
|
||||
05/05/2016 22:20:27: Finished Epoch[ 1 of 3]: [Training] TrainNodeClassBasedCrossEntropy = 6.83413224 * 2087; totalSamplesSeen = 2087; learningRatePerSample = 0.1; epochTime=13.6927s
|
||||
06/16/2016 10:51:18: Finished Epoch[ 1 of 3]: [Training] TrainNodeClassBasedCrossEntropy = 6.83413224 * 2087; totalSamplesSeen = 2087; learningRatePerSample = 0.1; epochTime=0.806587s
|
||||
LMSequenceReader: Reading epoch data... 3370 sequences read.
|
||||
LMSequenceReader: Reading epoch data... 0 sequences read.
|
||||
05/05/2016 22:21:20: Final Results: Minibatch[1-704]: TrainNodeClassBasedCrossEntropy = 6.52944688 * 73760; perplexity = 685.01920624
|
||||
05/05/2016 22:21:20: Finished Epoch[ 1 of 3]: [Validate] TrainNodeClassBasedCrossEntropy = 6.52944688 * 73760
|
||||
05/05/2016 22:21:20: SGD: Saving checkpoint model '/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/rnn.dnn.1'
|
||||
06/16/2016 10:51:25: Final Results: Minibatch[1-704]: TrainNodeClassBasedCrossEntropy = 6.52944686 * 73760; perplexity = 685.01919179
|
||||
06/16/2016 10:51:25: Finished Epoch[ 1 of 3]: [Validate] TrainNodeClassBasedCrossEntropy = 6.52944686 * 73760
|
||||
06/16/2016 10:51:25: SGD: Saving checkpoint model '/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/rnn.dnn.1'
|
||||
|
||||
05/05/2016 22:21:21: Starting Epoch 2: learning rate per sample = 0.100000 effective momentum = 0.000000 momentum as time constant = 0.0 samples
|
||||
06/16/2016 10:51:25: Starting Epoch 2: learning rate per sample = 0.100000 effective momentum = 0.000000 momentum as time constant = 0.0 samples
|
||||
|
||||
05/05/2016 22:21:21: Starting minibatch loop.
|
||||
06/16/2016 10:51:25: Starting minibatch loop.
|
||||
LMSequenceReader: Reading epoch data... 42068 sequences read.
|
||||
05/05/2016 22:21:29: Finished Epoch[ 2 of 3]: [Training] TrainNodeClassBasedCrossEntropy = 6.57536885 * 2099; totalSamplesSeen = 4186; learningRatePerSample = 0.1; epochTime=7.99991s
|
||||
06/16/2016 10:51:26: Finished Epoch[ 2 of 3]: [Training] TrainNodeClassBasedCrossEntropy = 6.57536839 * 2099; totalSamplesSeen = 4186; learningRatePerSample = 0.1; epochTime=0.669527s
|
||||
LMSequenceReader: Reading epoch data... 3370 sequences read.
|
||||
LMSequenceReader: Reading epoch data... 0 sequences read.
|
||||
05/05/2016 22:22:14: Final Results: Minibatch[1-353]: TrainNodeClassBasedCrossEntropy = 6.45979633 * 73760; perplexity = 638.93091153
|
||||
05/05/2016 22:22:14: Finished Epoch[ 2 of 3]: [Validate] TrainNodeClassBasedCrossEntropy = 6.45979633 * 73760
|
||||
05/05/2016 22:22:14: SGD: Saving checkpoint model '/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/rnn.dnn.2'
|
||||
06/16/2016 10:51:32: Final Results: Minibatch[1-353]: TrainNodeClassBasedCrossEntropy = 6.45979661 * 73760; perplexity = 638.93109334
|
||||
06/16/2016 10:51:32: Finished Epoch[ 2 of 3]: [Validate] TrainNodeClassBasedCrossEntropy = 6.45979661 * 73760
|
||||
06/16/2016 10:51:32: SGD: Saving checkpoint model '/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/rnn.dnn.2'
|
||||
|
||||
05/05/2016 22:22:14: Starting Epoch 3: learning rate per sample = 0.100000 effective momentum = 0.000000 momentum as time constant = 0.0 samples
|
||||
06/16/2016 10:51:32: Starting Epoch 3: learning rate per sample = 0.100000 effective momentum = 0.000000 momentum as time constant = 0.0 samples
|
||||
|
||||
05/05/2016 22:22:14: Starting minibatch loop.
|
||||
06/16/2016 10:51:32: Starting minibatch loop.
|
||||
LMSequenceReader: Reading epoch data... 42068 sequences read.
|
||||
05/05/2016 22:22:20: Finished Epoch[ 3 of 3]: [Training] TrainNodeClassBasedCrossEntropy = 7.26376970 * 2276; totalSamplesSeen = 6462; learningRatePerSample = 0.1; epochTime=5.82946s
|
||||
06/16/2016 10:51:33: Finished Epoch[ 3 of 3]: [Training] TrainNodeClassBasedCrossEntropy = 7.26366844 * 2276; totalSamplesSeen = 6462; learningRatePerSample = 0.1; epochTime=0.596137s
|
||||
LMSequenceReader: Reading epoch data... 3370 sequences read.
|
||||
LMSequenceReader: Reading epoch data... 0 sequences read.
|
||||
05/05/2016 22:23:02: Final Results: Minibatch[1-193]: TrainNodeClassBasedCrossEntropy = 9.55545905 * 73760; perplexity = 14121.57503880
|
||||
05/05/2016 22:23:02: Finished Epoch[ 3 of 3]: [Validate] TrainNodeClassBasedCrossEntropy = 9.55545905 * 73760
|
||||
05/05/2016 22:23:02: Loading (rolling back to) previous model with best training-criterion value: /tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/rnn.dnn.2.
|
||||
05/05/2016 22:23:02: learnRatePerSample reduced to 0.050000001
|
||||
05/05/2016 22:23:02: SGD: revoke back to and update checkpoint file for epoch 2
|
||||
06/16/2016 10:51:39: Final Results: Minibatch[1-193]: TrainNodeClassBasedCrossEntropy = 9.55520160 * 73760; perplexity = 14117.93994423
|
||||
06/16/2016 10:51:39: Finished Epoch[ 3 of 3]: [Validate] TrainNodeClassBasedCrossEntropy = 9.55520160 * 73760
|
||||
06/16/2016 10:51:39: Loading (rolling back to) previous model with best training-criterion value: /tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/rnn.dnn.2.
|
||||
06/16/2016 10:51:39: learnRatePerSample reduced to 0.050000001
|
||||
06/16/2016 10:51:39: SGD: revoke back to and update checkpoint file for epoch 2
|
||||
|
||||
05/05/2016 22:23:03: Starting Epoch 3: learning rate per sample = 0.050000 effective momentum = 0.000000 momentum as time constant = 0.0 samples
|
||||
06/16/2016 10:51:39: Starting Epoch 3: learning rate per sample = 0.050000 effective momentum = 0.000000 momentum as time constant = 0.0 samples
|
||||
|
||||
05/05/2016 22:23:03: Starting minibatch loop.
|
||||
06/16/2016 10:51:39: Starting minibatch loop.
|
||||
LMSequenceReader: Reading epoch data... 42068 sequences read.
|
||||
05/05/2016 22:23:08: Finished Epoch[ 3 of 3]: [Training] TrainNodeClassBasedCrossEntropy = 6.43178308 * 2276; totalSamplesSeen = 6462; learningRatePerSample = 0.050000001; epochTime=5.80466s
|
||||
06/16/2016 10:51:40: Finished Epoch[ 3 of 3]: [Training] TrainNodeClassBasedCrossEntropy = 6.43178908 * 2276; totalSamplesSeen = 6462; learningRatePerSample = 0.050000001; epochTime=0.585515s
|
||||
LMSequenceReader: Reading epoch data... 3370 sequences read.
|
||||
LMSequenceReader: Reading epoch data... 0 sequences read.
|
||||
05/05/2016 22:23:50: Final Results: Minibatch[1-193]: TrainNodeClassBasedCrossEntropy = 6.67105423 * 73760; perplexity = 789.22719648
|
||||
05/05/2016 22:23:50: Finished Epoch[ 3 of 3]: [Validate] TrainNodeClassBasedCrossEntropy = 6.67105423 * 73760
|
||||
05/05/2016 22:23:50: Loading (rolling back to) previous model with best training-criterion value: /tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/rnn.dnn.2.
|
||||
05/05/2016 22:23:50: learnRatePerSample reduced to 0.025
|
||||
05/05/2016 22:23:50: SGD: revoke back to and update checkpoint file for epoch 2
|
||||
06/16/2016 10:51:46: Final Results: Minibatch[1-193]: TrainNodeClassBasedCrossEntropy = 6.67106400 * 73760; perplexity = 789.23490530
|
||||
06/16/2016 10:51:46: Finished Epoch[ 3 of 3]: [Validate] TrainNodeClassBasedCrossEntropy = 6.67106400 * 73760
|
||||
06/16/2016 10:51:46: Loading (rolling back to) previous model with best training-criterion value: /tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/rnn.dnn.2.
|
||||
06/16/2016 10:51:46: learnRatePerSample reduced to 0.025
|
||||
06/16/2016 10:51:46: SGD: revoke back to and update checkpoint file for epoch 2
|
||||
|
||||
05/05/2016 22:23:51: Starting Epoch 3: learning rate per sample = 0.025000 effective momentum = 0.000000 momentum as time constant = 0.0 samples
|
||||
06/16/2016 10:51:46: Starting Epoch 3: learning rate per sample = 0.025000 effective momentum = 0.000000 momentum as time constant = 0.0 samples
|
||||
|
||||
05/05/2016 22:23:51: Starting minibatch loop.
|
||||
06/16/2016 10:51:46: Starting minibatch loop.
|
||||
LMSequenceReader: Reading epoch data... 42068 sequences read.
|
||||
05/05/2016 22:23:56: Finished Epoch[ 3 of 3]: [Training] TrainNodeClassBasedCrossEntropy = 6.24460230 * 2276; totalSamplesSeen = 6462; learningRatePerSample = 0.025; epochTime=5.80792s
|
||||
06/16/2016 10:51:47: Finished Epoch[ 3 of 3]: [Training] TrainNodeClassBasedCrossEntropy = 6.24460187 * 2276; totalSamplesSeen = 6462; learningRatePerSample = 0.025; epochTime=0.572276s
|
||||
LMSequenceReader: Reading epoch data... 3370 sequences read.
|
||||
LMSequenceReader: Reading epoch data... 0 sequences read.
|
||||
05/05/2016 22:24:38: Final Results: Minibatch[1-193]: TrainNodeClassBasedCrossEntropy = 6.42579765 * 73760; perplexity = 617.57322733
|
||||
05/05/2016 22:24:38: Finished Epoch[ 3 of 3]: [Validate] TrainNodeClassBasedCrossEntropy = 6.42579765 * 73760
|
||||
05/05/2016 22:24:38: SGD: Saving checkpoint model '/tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/Models/rnn.dnn'
|
||||
05/05/2016 22:24:38: CNTKCommandTrainEnd: train
|
||||
06/16/2016 10:51:53: Final Results: Minibatch[1-193]: TrainNodeClassBasedCrossEntropy = 6.42579772 * 73760; perplexity = 617.57327345
|
||||
06/16/2016 10:51:53: Finished Epoch[ 3 of 3]: [Validate] TrainNodeClassBasedCrossEntropy = 6.42579772 * 73760
|
||||
06/16/2016 10:51:53: SGD: Saving checkpoint model '/tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/Models/rnn.dnn'
|
||||
06/16/2016 10:51:53: CNTKCommandTrainEnd: train
|
||||
|
||||
05/05/2016 22:24:38: Action "train" complete.
|
||||
06/16/2016 10:51:53: Action "train" complete.
|
||||
|
||||
|
||||
05/05/2016 22:24:38: ##############################################################################
|
||||
05/05/2016 22:24:38: # #
|
||||
05/05/2016 22:24:38: # Action "eval" #
|
||||
05/05/2016 22:24:38: # #
|
||||
05/05/2016 22:24:38: ##############################################################################
|
||||
06/16/2016 10:51:53: ##############################################################################
|
||||
06/16/2016 10:51:53: # #
|
||||
06/16/2016 10:51:53: # Action "eval" #
|
||||
06/16/2016 10:51:53: # #
|
||||
06/16/2016 10:51:53: ##############################################################################
|
||||
|
||||
LMSequenceReader: Label mapping will be created internally on the fly because the labelMappingFile was not found: /tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.txt
|
||||
LMSequenceReader: Label mapping will be created internally on the fly because the labelMappingFile was not found: /tmp/cntk-test-20160505220136.870944/Examples/Text/PennTreebank_RNN@debug_cpu/sentenceLabels.out.txt
|
||||
LMSequenceReader: Label mapping will be created internally on the fly because the labelMappingFile was not found: /tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.txt
|
||||
LMSequenceReader: Label mapping will be created internally on the fly because the labelMappingFile was not found: /tmp/cntk-test-20160616105116.484664/Examples/Text/PennTreebank_RNN@release_cpu/sentenceLabels.out.txt
|
||||
|
||||
Post-processing network...
|
||||
|
||||
|
@ -1465,72 +1465,73 @@ Allocating matrices for forward and/or backward propagation.
|
|||
Memory Sharing Structure:
|
||||
|
||||
(nil): {[AutoName0 Gradient[200 x 1 x *1]] [AutoName1 Gradient[200 x 1 x *1]] [AutoName10 Gradient[200 x 1 x *1]] [AutoName11 Gradient[200 x 1 x *1]] [AutoName12 Gradient[200 x 1 x *1]] [AutoName13 Gradient[200 x 1 x *1]] [AutoName14 Gradient[200 x 1 x *1]] [AutoName15 Gradient[200 x 1 x *1]] [AutoName16 Gradient[200 x *1]] [AutoName17 Gradient[200 x 1 x *1]] [AutoName18 Gradient[200 x 1 x *1]] [AutoName19 Gradient[200 x 1 x *1]] [AutoName2 Gradient[200 x 1 x *1]] [AutoName20 Gradient[200 x 1 x *1]] [AutoName21 Gradient[200 x 1 x *1]] [AutoName22 Gradient[200 x *1]] [AutoName23 Gradient[200 x 1 x *1]] [AutoName24 Gradient[200 x 1 x *1]] [AutoName25 Gradient[200 x 1 x *1]] [AutoName26 Gradient[200 x 1 x *1]] [AutoName27 Gradient[200 x 1 x *1]] [AutoName28 Gradient[200 x 1 x *1]] [AutoName29 Gradient[200 x 1 x *1]] [AutoName3 Gradient[200 x 1 x *1]] [AutoName30 Gradient[200 x 1 x *1]] [AutoName31 Gradient[200 x *1]] [AutoName32 Gradient[200 x 1 x *1]] [AutoName33 Gradient[200 x 1 x *1]] [AutoName34 Gradient[200 x 1 x *1]] [AutoName35 Gradient[200 x 1 x *1]] [AutoName36 Gradient[200 x 1 x *1]] [AutoName37 Gradient[200 x 1 x *1]] [AutoName4 Gradient[200 x 1 x *1]] [AutoName5 Gradient[200 x 1 x *1]] [AutoName6 Gradient[200 x 1 x *1]] [AutoName7 Gradient[200 x 1 x *1]] [AutoName8 Gradient[200 x 1 x *1]] [AutoName9 Gradient[200 x *1]] [ClassPostProb Gradient[50 x 1 x *1]] [E0 Gradient[150 x 10000]] [LookupTable Gradient[150 x *1]] [PosteriorProb Gradient[10000 x 1 x *1]] [PosteriorProb Value[10000 x 1 x *1]] [TrainNodeClassBasedCrossEntropy Gradient[1]] [W2 Gradient[200 x 10000]] [WCF0 Gradient[200 x 1]] [WCI0 Gradient[200 x 1]] [WCO0 Gradient[200 x 1]] [WHC0 Gradient[200 x 200]] [WHF0 Gradient[200 x 200]] [WHI0 Gradient[200 x 200]] [WHO0 Gradient[200 x 200]] [WXC0 Gradient[200 x 150]] [WXF0 Gradient[200 x 150]] [WXI0 Gradient[200 x 150]] [WXO0 Gradient[200 x 150]] [WeightForClassPostProb Gradient[50 x 200]] [bc0 Gradient[200 x 1]] [bf0 Gradient[200 x 1]] [bi0 Gradient[200 x 1]] [bo0 Gradient[200 x 1]] [features Gradient[10000 x *1]] [labels Gradient[4 x *1]] [outputs Gradient[10000 x 1 x *1]] [outputs Value[10000 x 1 x *1]] }
|
||||
0x2df51a8: {[AutoName1 Value[200 x 1 x *1]] }
|
||||
0x47c30d8: {[features Value[10000 x *1]] }
|
||||
0x47d6e78: {[labels Value[4 x *1]] }
|
||||
0x47d88e8: {[W2 Value[200 x 10000]] }
|
||||
0x47d8d08: {[WCF0 Value[200 x 1]] }
|
||||
0x47d9528: {[WCI0 Value[200 x 1]] }
|
||||
0x47d96e8: {[WeightForClassPostProb Value[50 x 200]] }
|
||||
0x47d9d48: {[WCO0 Value[200 x 1]] }
|
||||
0x47d9f08: {[WHC0 Value[200 x 200]] }
|
||||
0x47db238: {[TrainNodeClassBasedCrossEntropy Value[1]] }
|
||||
0x47ede88: {[LookupTable Value[150 x *1]] }
|
||||
0x47ee228: {[AutoName31 Value[200 x *1]] }
|
||||
0x47eea98: {[AutoName22 Value[200 x *1]] }
|
||||
0x47eec58: {[AutoName23 Value[200 x 1 x *1]] }
|
||||
0x47ef2e8: {[AutoName32 Value[200 x 1 x *1]] }
|
||||
0x47ef9c8: {[AutoName9 Value[200 x *1]] }
|
||||
0x47efb88: {[AutoName10 Value[200 x 1 x *1]] }
|
||||
0x47efd48: {[AutoName16 Value[200 x *1]] }
|
||||
0x47eff08: {[AutoName30 Value[200 x 1 x *1]] }
|
||||
0x47f00c8: {[AutoName33 Value[200 x 1 x *1]] }
|
||||
0x47f0288: {[AutoName21 Value[200 x 1 x *1]] }
|
||||
0x47f0448: {[AutoName24 Value[200 x 1 x *1]] }
|
||||
0x47f0608: {[AutoName20 Value[200 x 1 x *1]] }
|
||||
0x47f07c8: {[AutoName25 Value[200 x 1 x *1]] }
|
||||
0x47f0988: {[AutoName26 Value[200 x 1 x *1]] }
|
||||
0x47f0b48: {[AutoName27 Value[200 x 1 x *1]] }
|
||||
0x47f0d08: {[AutoName8 Value[200 x 1 x *1]] }
|
||||
0x47f0ec8: {[AutoName11 Value[200 x 1 x *1]] }
|
||||
0x47f1088: {[AutoName7 Value[200 x 1 x *1]] }
|
||||
0x47f1248: {[AutoName12 Value[200 x 1 x *1]] }
|
||||
0x47f1408: {[AutoName13 Value[200 x 1 x *1]] }
|
||||
0x47f15c8: {[AutoName14 Value[200 x 1 x *1]] }
|
||||
0x47f1788: {[AutoName15 Value[200 x 1 x *1]] }
|
||||
0x47f1948: {[AutoName17 Value[200 x 1 x *1]] }
|
||||
0x47f1b08: {[AutoName18 Value[200 x 1 x *1]] }
|
||||
0x47f1cc8: {[AutoName19 Value[200 x 1 x *1]] }
|
||||
0x47f1e88: {[AutoName28 Value[200 x 1 x *1]] }
|
||||
0x47f2048: {[AutoName29 Value[200 x 1 x *1]] }
|
||||
0x47f2208: {[AutoName34 Value[200 x 1 x *1]] }
|
||||
0x47f23c8: {[AutoName35 Value[200 x 1 x *1]] }
|
||||
0x47f2588: {[AutoName36 Value[200 x 1 x *1]] }
|
||||
0x47f2748: {[AutoName37 Value[200 x 1 x *1]] }
|
||||
0x47f2908: {[ClassPostProb Value[50 x 1 x *1]] }
|
||||
0x484c2a8: {[WHF0 Value[200 x 200]] }
|
||||
0x484c778: {[WHI0 Value[200 x 200]] }
|
||||
0x484cc48: {[WHO0 Value[200 x 200]] }
|
||||
0x484d118: {[WXC0 Value[200 x 150]] }
|
||||
0x484d5e8: {[WXF0 Value[200 x 150]] }
|
||||
0x484dab8: {[WXI0 Value[200 x 150]] }
|
||||
0x484df88: {[WXO0 Value[200 x 150]] }
|
||||
0x48fef08: {[AutoName2 Value[200 x 1 x *1]] }
|
||||
0x49015a8: {[AutoName3 Value[200 x 1 x *1]] }
|
||||
0x4903578: {[AutoName4 Value[200 x 1 x *1]] }
|
||||
0x4903c48: {[AutoName5 Value[200 x 1 x *1]] }
|
||||
0x4904318: {[AutoName6 Value[200 x 1 x *1]] }
|
||||
0x4905238: {[bc0 Value[200 x 1]] }
|
||||
0x4905698: {[bf0 Value[200 x 1]] }
|
||||
0x4905e88: {[bi0 Value[200 x 1]] }
|
||||
0x4906678: {[bo0 Value[200 x 1]] }
|
||||
0x4906bc8: {[E0 Value[150 x 10000]] }
|
||||
0x6d663d8: {[AutoName0 Value[200 x 1 x *1]] }
|
||||
0x4d01f78: {[AutoName1 Value[200 x 1 x *1]] }
|
||||
0x4d04a98: {[AutoName2 Value[200 x 1 x *1]] }
|
||||
0x4d07138: {[AutoName3 Value[200 x 1 x *1]] }
|
||||
0x4d09108: {[AutoName4 Value[200 x 1 x *1]] }
|
||||
0x4d097d8: {[AutoName5 Value[200 x 1 x *1]] }
|
||||
0x4d09ea8: {[AutoName6 Value[200 x 1 x *1]] }
|
||||
0x4d0adc8: {[bc0 Value[200 x 1]] }
|
||||
0x4d0b228: {[bf0 Value[200 x 1]] }
|
||||
0x4d0ba18: {[bi0 Value[200 x 1]] }
|
||||
0x4d0c208: {[bo0 Value[200 x 1]] }
|
||||
0x4d0c758: {[E0 Value[150 x 10000]] }
|
||||
0x4da9778: {[AutoName7 Value[200 x 1 x *1]] }
|
||||
0x4da9938: {[AutoName12 Value[200 x 1 x *1]] }
|
||||
0x4da9af8: {[AutoName13 Value[200 x 1 x *1]] }
|
||||
0x4da9cb8: {[AutoName14 Value[200 x 1 x *1]] }
|
||||
0x4da9e78: {[AutoName15 Value[200 x 1 x *1]] }
|
||||
0x4daa038: {[AutoName17 Value[200 x 1 x *1]] }
|
||||
0x4daa1f8: {[AutoName18 Value[200 x 1 x *1]] }
|
||||
0x4daa3b8: {[AutoName19 Value[200 x 1 x *1]] }
|
||||
0x4daa578: {[AutoName28 Value[200 x 1 x *1]] }
|
||||
0x4daa738: {[AutoName29 Value[200 x 1 x *1]] }
|
||||
0x4daa8f8: {[AutoName34 Value[200 x 1 x *1]] }
|
||||
0x4daaab8: {[AutoName35 Value[200 x 1 x *1]] }
|
||||
0x4daac78: {[AutoName36 Value[200 x 1 x *1]] }
|
||||
0x4daae38: {[AutoName37 Value[200 x 1 x *1]] }
|
||||
0x4daaff8: {[ClassPostProb Value[50 x 1 x *1]] }
|
||||
0x55a6348: {[features Value[10000 x *1]] }
|
||||
0x55ba0e8: {[labels Value[4 x *1]] }
|
||||
0x55bbb58: {[W2 Value[200 x 10000]] }
|
||||
0x55bbf78: {[WCF0 Value[200 x 1]] }
|
||||
0x55bc798: {[WCI0 Value[200 x 1]] }
|
||||
0x55bc958: {[WeightForClassPostProb Value[50 x 200]] }
|
||||
0x55bcfb8: {[WCO0 Value[200 x 1]] }
|
||||
0x55bd178: {[WHC0 Value[200 x 200]] }
|
||||
0x55be1b8: {[WHF0 Value[200 x 200]] }
|
||||
0x55be688: {[WHI0 Value[200 x 200]] }
|
||||
0x55beb58: {[WHO0 Value[200 x 200]] }
|
||||
0x55bf028: {[WXC0 Value[200 x 150]] }
|
||||
0x55bf4f8: {[WXF0 Value[200 x 150]] }
|
||||
0x55bf9c8: {[WXI0 Value[200 x 150]] }
|
||||
0x55bfe98: {[WXO0 Value[200 x 150]] }
|
||||
0x55c04c8: {[TrainNodeClassBasedCrossEntropy Value[1]] }
|
||||
0x55d4278: {[LookupTable Value[150 x *1]] }
|
||||
0x55d4618: {[AutoName31 Value[200 x *1]] }
|
||||
0x55d4e88: {[AutoName22 Value[200 x *1]] }
|
||||
0x55d5048: {[AutoName23 Value[200 x 1 x *1]] }
|
||||
0x55d56d8: {[AutoName32 Value[200 x 1 x *1]] }
|
||||
0x55d5db8: {[AutoName9 Value[200 x *1]] }
|
||||
0x55d5f78: {[AutoName10 Value[200 x 1 x *1]] }
|
||||
0x55d6138: {[AutoName16 Value[200 x *1]] }
|
||||
0x55d62f8: {[AutoName30 Value[200 x 1 x *1]] }
|
||||
0x55d64b8: {[AutoName33 Value[200 x 1 x *1]] }
|
||||
0x55d6678: {[AutoName21 Value[200 x 1 x *1]] }
|
||||
0x55d6838: {[AutoName24 Value[200 x 1 x *1]] }
|
||||
0x55d69f8: {[AutoName20 Value[200 x 1 x *1]] }
|
||||
0x55d6bb8: {[AutoName25 Value[200 x 1 x *1]] }
|
||||
0x55d6d78: {[AutoName26 Value[200 x 1 x *1]] }
|
||||
0x55d6f38: {[AutoName27 Value[200 x 1 x *1]] }
|
||||
0x55d70f8: {[AutoName8 Value[200 x 1 x *1]] }
|
||||
0x55d72b8: {[AutoName11 Value[200 x 1 x *1]] }
|
||||
0x611f698: {[AutoName0 Value[200 x 1 x *1]] }
|
||||
|
||||
LMSequenceReader: Reading epoch data... 3760 sequences read.
|
||||
LMSequenceReader: Reading epoch data... 0 sequences read.
|
||||
05/05/2016 22:25:22: Final Results: Minibatch[1-60]: TrainNodeClassBasedCrossEntropy = 6.37864559 * 82402; perplexity = 589.12924332
|
||||
06/16/2016 10:51:59: Minibatch[1-60]: TrainNodeClassBasedCrossEntropy = 6.37864556 * 82402
|
||||
06/16/2016 10:51:59: Final Results: Minibatch[1-60]: TrainNodeClassBasedCrossEntropy = 6.37864556 * 82402; perplexity = 589.12922778
|
||||
|
||||
05/05/2016 22:25:22: Action "eval" complete.
|
||||
06/16/2016 10:51:59: Action "eval" complete.
|
||||
|
||||
05/05/2016 22:25:22: __COMPLETED__
|
||||
06/16/2016 10:51:59: __COMPLETED__
|
|
@ -31,4 +31,4 @@ testCases:
|
|||
- Minibatch[{{integer}}-{{integer}}
|
||||
- " * {{integer}}; "
|
||||
- TrainNodeClassBasedCrossEntropy = {{float,tolerance=0.05}}
|
||||
- perplexity = {{float,tolerance=0.05}}
|
||||
- perplexity = {{float,tolerance=0.1%}}
|
||||
|
|
|
@ -0,0 +1,189 @@
|
|||
#!/usr/bin/env python
|
||||
# ----------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
|
||||
# ---------------------------------------------------------
|
||||
# This script extracts information (hardware used, final results) contained in the baselines files
|
||||
# and generates a markdown file (wiki page)
|
||||
|
||||
import sys, os, re
|
||||
import TestDriver as td
|
||||
|
||||
try:
|
||||
import six
|
||||
except ImportError:
|
||||
print("Python package 'six' not installed. Please run 'pip install six'.")
|
||||
sys.exit(1)
|
||||
|
||||
thisDir = os.path.dirname(os.path.realpath(__file__))
|
||||
windows = os.getenv("OS")=="Windows_NT"
|
||||
|
||||
class Baseline:
|
||||
def __init__(self, fullPath, testResult = "", trainResult = ""):
|
||||
self.fullPath = fullPath
|
||||
self.cpuInfo = ""
|
||||
self.gpuInfo = ""
|
||||
self.testResult = testResult
|
||||
self.trainResult = trainResult
|
||||
|
||||
# extracts results info. e.g.
|
||||
# Finished Epoch[ 5 of 5]: [Training] ce = 2.32253198 * 1000 err = 0.90000000 * 1000 totalSamplesSeen = 5000 learningRatePerSample = 2e-06 epochTime=0.175781
|
||||
# Final Results: Minibatch[1-1]: err = 0.90000000 * 100 ce = 2.32170486 * 100 perplexity = 10.1930372
|
||||
def extractResultsInfo(self, baselineContent):
|
||||
trainResults = re.findall('.*(Finished Epoch\[ *\d+ of \d+\]\: \[Training\]) (.*)', baselineContent)
|
||||
if trainResults:
|
||||
self.trainResult = Baseline.formatLastTrainResult(trainResults[-1])[0:-2]
|
||||
testResults = re.findall('.*(Final Results: Minibatch\[1-\d+\]:)(\s+\* \d+)?\s+(.*)', baselineContent)
|
||||
if testResults:
|
||||
self.testResult = Baseline.formatLastTestResult(testResults[-1])[0:-2]
|
||||
|
||||
# extracts cpu and gpu info from baseline content. e.g.:
|
||||
#CPU info:
|
||||
# CPU Model Name: Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz
|
||||
# Hardware threads: 12
|
||||
#GPU info:
|
||||
#
|
||||
#Device[0]: cores = 2496; computeCapability = 5.2; type = "Quadro M4000"; memory = 8192 MB
|
||||
#Device[1]: cores = 96; computeCapability = 2.1; type = "Quadro 600"; memory = 1024 MB
|
||||
# Total Memory: 33474872 kB
|
||||
def extractHardwareInfo(self, baselineContent):
|
||||
startCpuInfoIndex = baselineContent.find("CPU info:")
|
||||
endCpuInfoIndex = baselineContent.find("----------", startCpuInfoIndex)
|
||||
cpuInfo = re.search("^CPU info:\s+"
|
||||
"CPU Model (Name:\s*.*)\s+"
|
||||
"(Hardware threads: \d+)\s+"
|
||||
"Total (Memory:\s*.*)\s+", baselineContent[startCpuInfoIndex:endCpuInfoIndex], re.MULTILINE)
|
||||
if cpuInfo is None:
|
||||
return
|
||||
self.cpuInfo = "\n".join(cpuInfo.groups())
|
||||
|
||||
startGpuInfoIndex = baselineContent.find("GPU info:")
|
||||
endGpuInfoIndex = baselineContent.find("----------", startGpuInfoIndex)
|
||||
gpuInfoSnippet = baselineContent[startGpuInfoIndex:endGpuInfoIndex]
|
||||
|
||||
gpuDevices = re.findall("\t\t(Device\[\d+\]: cores = \d+; computeCapability = \d\.\d; type = .*; memory = \d+ MB)[\r\n]?", gpuInfoSnippet)
|
||||
if not gpuDevices:
|
||||
return
|
||||
gpuInfo = [ device for device in gpuDevices ]
|
||||
self.gpuInfo = "\n".join(gpuInfo)
|
||||
|
||||
@staticmethod
|
||||
def formatLastTestResult(line):
|
||||
return line[0] + line[1] + "\n" + line[2].replace('; ', '\n').replace(' ','\n')
|
||||
|
||||
@staticmethod
|
||||
def formatLastTrainResult(line):
|
||||
epochsInfo, parameters = line[0], line[1]
|
||||
return epochsInfo + '\n' + parameters.replace('; ', '\n')
|
||||
|
||||
class Example:
|
||||
|
||||
allExamplesIndexedByFullName = {}
|
||||
|
||||
def __init__(self, suite, name, testDir):
|
||||
self.suite = suite
|
||||
self.name = name
|
||||
self.fullName = suite + "/" + name
|
||||
self.testDir = testDir
|
||||
self.baselineList = []
|
||||
|
||||
self.gitHash = ""
|
||||
|
||||
@staticmethod
|
||||
def discoverAllExamples():
|
||||
testsDir = thisDir
|
||||
for dirName, subdirList, fileList in os.walk(testsDir):
|
||||
if 'testcases.yml' in fileList:
|
||||
testDir = dirName
|
||||
exampleName = os.path.basename(dirName)
|
||||
suiteDir = os.path.dirname(dirName)
|
||||
# suite name will be derived from the path components
|
||||
suiteName = os.path.relpath(suiteDir, testsDir).replace('\\', '/')
|
||||
|
||||
example = Example(suiteName, exampleName, testDir)
|
||||
Example.allExamplesIndexedByFullName[example.fullName.lower()] = example
|
||||
|
||||
# it returns a list with all baseline files for current example
|
||||
def findBaselineFilesList(self):
|
||||
baselineFilesList = []
|
||||
|
||||
oses = [".windows", ".linux", ""]
|
||||
devices = [".cpu", ".gpu", ""]
|
||||
flavors = [".debug", ".release", ""]
|
||||
|
||||
for o in oses:
|
||||
for device in devices:
|
||||
for flavor in flavors:
|
||||
candidateName = "baseline" + o + flavor + device + ".txt"
|
||||
fullPath = td.cygpath(os.path.join(self.testDir, candidateName), relative=True)
|
||||
if os.path.isfile(fullPath):
|
||||
baseline = Baseline(fullPath);
|
||||
baselineFilesList.append(baseline)
|
||||
|
||||
return baselineFilesList
|
||||
|
||||
# extracts information for every example and stores it in Example.allExamplesIndexedByFullName
|
||||
def getExamplesMetrics():
|
||||
Example.allExamplesIndexedByFullName = list(sorted(Example.allExamplesIndexedByFullName.values(), key=lambda test: test.fullName))
|
||||
allExamples = Example.allExamplesIndexedByFullName
|
||||
|
||||
print ("CNTK - Metrics collector")
|
||||
|
||||
for example in allExamples:
|
||||
baselineListForExample = example.findBaselineFilesList()
|
||||
six.print_("Example: " + example.fullName)
|
||||
for baseline in baselineListForExample:
|
||||
with open(baseline.fullPath, "r") as f:
|
||||
baselineContent = f.read()
|
||||
gitHash = re.search('.*Build SHA1:\s([a-z0-9]{40})[\r\n]+', baselineContent, re.MULTILINE)
|
||||
if gitHash is None:
|
||||
continue
|
||||
example.gitHash = gitHash.group(1)
|
||||
baseline.extractHardwareInfo(baselineContent)
|
||||
baseline.extractResultsInfo(baselineContent)
|
||||
example.baselineList.append(baseline)
|
||||
|
||||
# creates a list with links to each example result
|
||||
def createAsciidocExampleList(file):
|
||||
for example in Example.allExamplesIndexedByFullName:
|
||||
if not example.baselineList:
|
||||
continue
|
||||
file.write("".join(["<<", example.fullName.replace("/","").lower(),",", example.fullName, ">> +\n"]))
|
||||
file.write("\n")
|
||||
|
||||
def writeMetricsToAsciidoc():
|
||||
metricsFile = open("metrics.adoc",'wb')
|
||||
|
||||
createAsciidocExampleList(metricsFile)
|
||||
|
||||
for example in Example.allExamplesIndexedByFullName:
|
||||
if not example.baselineList:
|
||||
continue
|
||||
metricsFile.write("".join(["===== ", example.fullName, "\n"]))
|
||||
metricsFile.write("".join(["**Git Hash: **", example.gitHash, "\n\n"]))
|
||||
metricsFile.write("[cols=3, options=\"header\"]\n")
|
||||
metricsFile.write("|====\n")
|
||||
metricsFile.write("|Log file / Configuration | Train Result | Test Result\n")
|
||||
for baseline in example.baselineList:
|
||||
pathInDir=baseline.fullPath.split(thisDir)[1][1:]
|
||||
metricsFile.write("".join(["|link:../blob/", example.gitHash[:7],"/Tests/EndToEndTests/", pathInDir, "[",
|
||||
baseline.fullPath.split("/")[-1], "] .2+|", baseline.trainResult.replace("\n", " "), " .2+|",
|
||||
baseline.testResult.replace("\n", " "), "|\n"]))
|
||||
cpuInfo = "".join(["CPU: ", re.sub("[\r]?\n", ' ', baseline.cpuInfo)])
|
||||
|
||||
gpuInfo = re.sub("[\r]?\n", ' ', baseline.gpuInfo)
|
||||
if gpuInfo:
|
||||
metricsFile.write("".join([cpuInfo, " GPU: ", gpuInfo]))
|
||||
else:
|
||||
metricsFile.write(cpuInfo)
|
||||
|
||||
metricsFile.write("\n|====\n\n")
|
||||
|
||||
# ======================= Entry point =======================
|
||||
six.print_("==============================================================================")
|
||||
|
||||
Example.discoverAllExamples()
|
||||
|
||||
getExamplesMetrics()
|
||||
|
||||
writeMetricsToAsciidoc()
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python
|
||||
# ----------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# ---------------------------------------------------------
|
||||
|
@ -687,89 +687,90 @@ def runCommand(args):
|
|||
sys.exit(10)
|
||||
|
||||
# ======================= Entry point =======================
|
||||
parser = argparse.ArgumentParser(description="TestDriver - CNTK Test Driver")
|
||||
subparsers = parser.add_subparsers(help="command to execute. Run TestDriver.py <command> --help for command-specific help")
|
||||
runSubparser = subparsers.add_parser("run", help="run test(s)")
|
||||
runSubparser.add_argument("test", nargs="*",
|
||||
help="optional test name(s) to run, specified as Suite/TestName. "
|
||||
"Use list command to list available tests. "
|
||||
"If not specified then all tests will be run.")
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="TestDriver - CNTK Test Driver")
|
||||
subparsers = parser.add_subparsers(help="command to execute. Run TestDriver.py <command> --help for command-specific help")
|
||||
runSubparser = subparsers.add_parser("run", help="run test(s)")
|
||||
runSubparser.add_argument("test", nargs="*",
|
||||
help="optional test name(s) to run, specified as Suite/TestName. "
|
||||
"Use list command to list available tests. "
|
||||
"If not specified then all tests will be run.")
|
||||
|
||||
defaultBuildSKU = "gpu"
|
||||
defaultBuildSKU = "gpu"
|
||||
|
||||
runSubparser.add_argument("-b", "--build-location", help="location of the CNTK build to run")
|
||||
runSubparser.add_argument("-t", "--tag", help="runs tests which match the specified tag")
|
||||
runSubparser.add_argument("-d", "--device", help="cpu|gpu - run on a specified device")
|
||||
runSubparser.add_argument("-f", "--flavor", help="release|debug - run only a specified flavor")
|
||||
runSubparser.add_argument("-s", "--build-sku", default=defaultBuildSKU, help="cpu|gpu|1bitsgd - run tests only for a specified build SKU")
|
||||
tmpDir = os.getenv("TEMP") if windows else "/tmp"
|
||||
defaultRunDir=os.path.join(tmpDir, "cntk-test-{0}.{1}".format(time.strftime("%Y%m%d%H%M%S"), random.randint(0,1000000)))
|
||||
runSubparser.add_argument("-r", "--run-dir", default=defaultRunDir, help="directory where to store test output, default: a random dir within /tmp")
|
||||
runSubparser.add_argument("--update-baseline", action='store_true', help="update baseline file(s) instead of matching them")
|
||||
runSubparser.add_argument("--create-baseline", action='store_true', help="create new baseline file(s) (named as baseline.<os>.<device>.txt) for tests that do not currently have baselines")
|
||||
runSubparser.add_argument("-v", "--verbose", action='store_true', help="verbose output - dump all output of test script")
|
||||
runSubparser.add_argument("-n", "--dry-run", action='store_true', help="do not run the tests, only print test names and configurations to be run along with full command lines")
|
||||
runSubparser.add_argument("-b", "--build-location", help="location of the CNTK build to run")
|
||||
runSubparser.add_argument("-t", "--tag", help="runs tests which match the specified tag")
|
||||
runSubparser.add_argument("-d", "--device", help="cpu|gpu - run on a specified device")
|
||||
runSubparser.add_argument("-f", "--flavor", help="release|debug - run only a specified flavor")
|
||||
runSubparser.add_argument("-s", "--build-sku", default=defaultBuildSKU, help="cpu|gpu|1bitsgd - run tests only for a specified build SKU")
|
||||
tmpDir = os.getenv("TEMP") if windows else "/tmp"
|
||||
defaultRunDir=os.path.join(tmpDir, "cntk-test-{0}.{1}".format(time.strftime("%Y%m%d%H%M%S"), random.randint(0,1000000)))
|
||||
runSubparser.add_argument("-r", "--run-dir", default=defaultRunDir, help="directory where to store test output, default: a random dir within /tmp")
|
||||
runSubparser.add_argument("--update-baseline", action='store_true', help="update baseline file(s) instead of matching them")
|
||||
runSubparser.add_argument("--create-baseline", action='store_true', help="create new baseline file(s) (named as baseline.<os>.<device>.txt) for tests that do not currently have baselines")
|
||||
runSubparser.add_argument("-v", "--verbose", action='store_true', help="verbose output - dump all output of test script")
|
||||
runSubparser.add_argument("-n", "--dry-run", action='store_true', help="do not run the tests, only print test names and configurations to be run along with full command lines")
|
||||
|
||||
runSubparser.set_defaults(func=runCommand)
|
||||
runSubparser.set_defaults(func=runCommand)
|
||||
|
||||
listSubparser = subparsers.add_parser("list", help="list available tests")
|
||||
listSubparser.add_argument("-t", "--tag", help="limits a resulting list to tests matching the specified tag")
|
||||
listSubparser.add_argument("-d", "--device", help="cpu|gpu - tests for a specified device")
|
||||
listSubparser.add_argument("-f", "--flavor", help="release|debug - tests for specified flavor")
|
||||
listSubparser.add_argument("-s", "--build-sku", default=defaultBuildSKU, help="cpu|gpu|1bitsgd - list tests only for a specified build SKU")
|
||||
listSubparser.add_argument("--os", help="windows|linux - tests for a specified operating system")
|
||||
listSubparser = subparsers.add_parser("list", help="list available tests")
|
||||
listSubparser.add_argument("-t", "--tag", help="limits a resulting list to tests matching the specified tag")
|
||||
listSubparser.add_argument("-d", "--device", help="cpu|gpu - tests for a specified device")
|
||||
listSubparser.add_argument("-f", "--flavor", help="release|debug - tests for specified flavor")
|
||||
listSubparser.add_argument("-s", "--build-sku", default=defaultBuildSKU, help="cpu|gpu|1bitsgd - list tests only for a specified build SKU")
|
||||
listSubparser.add_argument("--os", help="windows|linux - tests for a specified operating system")
|
||||
|
||||
listSubparser.set_defaults(func=listCommand)
|
||||
listSubparser.set_defaults(func=listCommand)
|
||||
|
||||
if len(sys.argv)==1:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
args = parser.parse_args(sys.argv[1:])
|
||||
|
||||
# parsing a --device, --flavor and --os options:
|
||||
args.devices = ["cpu", "gpu"]
|
||||
if (args.device):
|
||||
args.device = args.device.lower()
|
||||
if not args.device in args.devices:
|
||||
six.print_("--device must be one of", args.devices, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
args.devices = [args.device]
|
||||
|
||||
args.flavors = ["debug", "release"]
|
||||
if (args.flavor):
|
||||
args.flavor = args.flavor.lower()
|
||||
if not args.flavor in args.flavors:
|
||||
six.print_("--flavor must be one of", args.flavors, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
args.flavors = [args.flavor]
|
||||
|
||||
args.buildSKUs = ["cpu", "gpu", "1bitsgd"]
|
||||
if (args.build_sku):
|
||||
args.build_sku = args.build_sku.lower()
|
||||
if not args.build_sku in args.buildSKUs:
|
||||
six.print_("--build-sku must be one of", args.buildSKUs, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
args.buildSKUs = [args.build_sku]
|
||||
if args.build_sku == "cpu" and args.devices == ["gpu"]:
|
||||
print >>sys.stderr, "Invalid combination: --build-sku cpu and --device gpu"
|
||||
sys.exit(1)
|
||||
|
||||
if args.func == runCommand and not args.build_location:
|
||||
args.build_location = os.path.realpath(os.path.join(thisDir, "../..", "x64" if windows else "build/"))
|
||||
|
||||
if args.func == listCommand:
|
||||
args.oses = ["windows", "linux"]
|
||||
if (args.os):
|
||||
args.os = args.os.lower()
|
||||
if not args.os in args.oses:
|
||||
six.print_("--os must be one of", args.oses, file=sys.stderr)
|
||||
if len(sys.argv)==1:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
args.oses = [args.os]
|
||||
|
||||
# discover all the tests
|
||||
Test.discoverAllTests()
|
||||
args = parser.parse_args(sys.argv[1:])
|
||||
|
||||
# execute the command
|
||||
args.func(args)
|
||||
# parsing a --device, --flavor and --os options:
|
||||
args.devices = ["cpu", "gpu"]
|
||||
if (args.device):
|
||||
args.device = args.device.lower()
|
||||
if not args.device in args.devices:
|
||||
six.print_("--device must be one of", args.devices, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
args.devices = [args.device]
|
||||
|
||||
args.flavors = ["debug", "release"]
|
||||
if (args.flavor):
|
||||
args.flavor = args.flavor.lower()
|
||||
if not args.flavor in args.flavors:
|
||||
six.print_("--flavor must be one of", args.flavors, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
args.flavors = [args.flavor]
|
||||
|
||||
args.buildSKUs = ["cpu", "gpu", "1bitsgd"]
|
||||
if (args.build_sku):
|
||||
args.build_sku = args.build_sku.lower()
|
||||
if not args.build_sku in args.buildSKUs:
|
||||
six.print_("--build-sku must be one of", args.buildSKUs, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
args.buildSKUs = [args.build_sku]
|
||||
if args.build_sku == "cpu" and args.devices == ["gpu"]:
|
||||
print >>sys.stderr, "Invalid combination: --build-sku cpu and --device gpu"
|
||||
sys.exit(1)
|
||||
|
||||
if args.func == runCommand and not args.build_location:
|
||||
args.build_location = os.path.realpath(os.path.join(thisDir, "../..", "x64" if windows else "build/"))
|
||||
|
||||
if args.func == listCommand:
|
||||
args.oses = ["windows", "linux"]
|
||||
if (args.os):
|
||||
args.os = args.os.lower()
|
||||
if not args.os in args.oses:
|
||||
six.print_("--os must be one of", args.oses, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
args.oses = [args.os]
|
||||
|
||||
# discover all the tests
|
||||
Test.discoverAllTests()
|
||||
|
||||
# execute the command
|
||||
args.func(args)
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#!/bin/bash
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
|
||||
# ----------------------------------------------------------
|
||||
# Helper script containing common code used by run-test scripts of E2E tests
|
||||
|
||||
BinaryPath=$TEST_CNTK_BINARY
|
||||
|
@ -26,6 +29,21 @@ MPIArgs=
|
|||
DeleteExistingModels=1
|
||||
DeleteModelsAfterTest=1
|
||||
|
||||
# Print info needed by MetricsDriver.py to extract tests metrics
|
||||
printHardwareInfo()
|
||||
{
|
||||
cpuName=$(cat /proc/cpuinfo 2> /dev/null | grep -m 1 'model name' | cut -d : -f 2- | tr -s " " | cut -c 2-)
|
||||
totalMemory=$(cat /proc/meminfo 2> /dev/null | grep 'MemTotal' | cut -d : -f 2- | tr -s " " | cut -c 2-)
|
||||
nproc=$(nproc)
|
||||
|
||||
# Note that MetricsDriver.py depends on this format
|
||||
echo "CPU info:"
|
||||
echo " CPU Model Name: $cpuName"
|
||||
echo " Hardware threads: $nproc"
|
||||
echo " Total Memory: $totalMemory"
|
||||
echo "-------------------------------------------------------------------"
|
||||
}
|
||||
|
||||
# Helper function to print and run a command
|
||||
run()
|
||||
{
|
||||
|
@ -119,3 +137,6 @@ cntkmpirun()
|
|||
cntkrun "$2" "$3"
|
||||
return $?
|
||||
}
|
||||
|
||||
# place printHardwareInfo here, so that all tests print it
|
||||
printHardwareInfo
|
||||
|
|
|
@ -145,13 +145,50 @@ template<typename ScalarCT> void CompareMatricesAndDump(const ScalarCT* ref, con
|
|||
|
||||
BOOST_AUTO_TEST_SUITE(BlockMultiplierSuite)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(BlockMultiplyTest)
|
||||
BOOST_AUTO_TEST_CASE(BlockMultiplyTest8x128x8SingleThread)
|
||||
{
|
||||
TestMultiplierSub<int16_t, int16_t, int32_t, BlockMultiplier<BlockHandlerSSE>>(8, 128, 8, 1);
|
||||
}
|
||||
|
||||
int m = 8;
|
||||
int k = 128;
|
||||
int n = 8;
|
||||
TestMultiplierSub<int16_t, int16_t, int32_t, BlockMultiplier<BlockHandlerSSE>>(m, k, n);
|
||||
// Test with numblocks > 4 && numblocks % 4 != 0
|
||||
BOOST_AUTO_TEST_CASE(BlockMultiplyTest7x128x8SingleThread)
|
||||
{
|
||||
TestMultiplierSub<int16_t, int16_t, int32_t, BlockMultiplier<BlockHandlerSSE>>(7, 128, 8, 1);
|
||||
}
|
||||
|
||||
// Test that hits all the kernel functions in BlockMultiplier (single row)
|
||||
BOOST_AUTO_TEST_CASE(BlockMultiplyTestAllKSingleRowSingleThread)
|
||||
{
|
||||
TestMultiplierSub<int16_t, int16_t, int32_t, BlockMultiplier<BlockHandlerSSE>>(1, 128 + 64 + 32 + 16 + 8 + 1, 1, 1);
|
||||
}
|
||||
|
||||
// Test that hits all the kernel functions in BlockMultiplier (four rows)
|
||||
BOOST_AUTO_TEST_CASE(BlockMultiplyTestAllKFourRowsSingleThread)
|
||||
{
|
||||
TestMultiplierSub<int16_t, int16_t, int32_t, BlockMultiplier<BlockHandlerSSE>>(4, 128 + 64 + 32 + 16 + 8 + 1, 1, 1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(BlockMultiplyTest8x128x8MultiThread)
|
||||
{
|
||||
TestMultiplierSub<int16_t, int16_t, int32_t, BlockMultiplier<BlockHandlerSSE>>(8, 128, 8, 2);
|
||||
}
|
||||
|
||||
// Test with numblocks > 4 && numblocks % 4 != 0
|
||||
BOOST_AUTO_TEST_CASE(BlockMultiplyTest7x128x8MultiThread)
|
||||
{
|
||||
TestMultiplierSub<int16_t, int16_t, int32_t, BlockMultiplier<BlockHandlerSSE>>(7, 128, 8, 2);
|
||||
}
|
||||
|
||||
// Test that hits all the kernel functions in BlockMultiplier (single row)
|
||||
BOOST_AUTO_TEST_CASE(BlockMultiplyTestAllKSingleRowMultiThread)
|
||||
{
|
||||
TestMultiplierSub<int16_t, int16_t, int32_t, BlockMultiplier<BlockHandlerSSE>>(1, 128 + 64 + 32 + 16 + 8 + 1, 1, 2);
|
||||
}
|
||||
|
||||
// Test that hits all the kernel functions in BlockMultiplier (four rows)
|
||||
BOOST_AUTO_TEST_CASE(BlockMultiplyTestAllKFourRowsMultiThread)
|
||||
{
|
||||
TestMultiplierSub<int16_t, int16_t, int32_t, BlockMultiplier<BlockHandlerSSE>>(4, 128 + 64 + 32 + 16 + 8 + 1, 1, 2);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
|
@ -29,12 +29,7 @@
|
|||
<PropertyGroup>
|
||||
<HasBoost>false</HasBoost>
|
||||
<HasBoost Condition="Exists('$(BOOST_INCLUDE_PATH)') And Exists('$(BOOST_LIB_PATH)')">true</HasBoost>
|
||||
<HasOpenCV>false</HasOpenCV>
|
||||
<HasOpenCV Condition="Exists('$(OPENCV_PATH)')">true</HasOpenCV>
|
||||
<ImageReaderDefine Condition="$(HasOpenCV)">ENABLE_IMAGEREADER_TESTS</ImageReaderDefine>
|
||||
<UseZip>false</UseZip>
|
||||
<UseZip Condition="Exists('$(ZLIB_PATH)')">true</UseZip>
|
||||
<ZipDefine Condition="$(HasOpenCV) And $(UseZip)">USE_ZIP</ZipDefine>
|
||||
<ImageReaderDefine Condition="$(HasOpenCv)">ENABLE_IMAGEREADER_TESTS</ImageReaderDefine>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
|
@ -257,8 +252,8 @@
|
|||
<Target Name="CheckDependencies">
|
||||
<Warning Condition="!$(HasBoost)" Text="ReaderTests requires the Boost library to build. Please see https://github.com/Microsoft/CNTK/wiki/Setup-CNTK-on-Windows#boost for installation instructions." />
|
||||
</Target>
|
||||
<PropertyGroup Condition="$(HasOpenCV)">
|
||||
<ImageReaderDependencies>$(OutDir)..\ImageReader.dll;$(OPENCV_PATH)\x64\vc12\bin\opencv_world300.dll</ImageReaderDependencies>
|
||||
<PropertyGroup Condition="$(HasOpenCv)">
|
||||
<ImageReaderDependencies>$(OutDir)..\ImageReader.dll;$(OpenCvBinPath)\$(OpenCvWorld).dll</ImageReaderDependencies>
|
||||
<ImageReaderDependencies Condition="$(UseZip)">$(ImageReaderDependencies);$(OutDir)..\zip.dll;$(OutDir)..\zlib1.dll</ImageReaderDependencies>
|
||||
</PropertyGroup>
|
||||
<Target Name="CopyUnitTestDependencies" AfterTargets="Build">
|
||||
|
|
|
@ -44,7 +44,7 @@ void TestFeedForwardNetworkCreation(const DeviceDescriptor& device)
|
|||
|
||||
Variable labelsVar({ numOutputClasses }, DataType::Float, L"Labels");
|
||||
auto trainingLossFunction = CNTK::CrossEntropyWithSoftmax(classifierOutputFunction, labelsVar, L"LossFunction");
|
||||
auto predictionFunction = CNTK::PredictionError(classifierOutputFunction, labelsVar, L"PredictionError");
|
||||
auto predictionFunction = CNTK::ClassificationError(classifierOutputFunction, labelsVar, L"ClassificationError");
|
||||
|
||||
auto ffNet = CNTK::Combine({ trainingLossFunction, predictionFunction, classifierOutputFunction }, L"ClassifierModel");
|
||||
|
||||
|
@ -128,7 +128,7 @@ void TestTimesAndPlus(size_t inputDim,
|
|||
if (usePreAllocatedOutputs)
|
||||
{
|
||||
auto outputAllocationDevice = outputOnSpecifiedDevice ? device : DeviceDescriptor::CPUDevice();
|
||||
if (outputAllocationDevice.Type() == DeviceType::CPU)
|
||||
if (outputAllocationDevice.Type() == DeviceKind::CPU)
|
||||
outputValue = new Value(new NDArrayView(outputShape, outputData.data(), outputData.size(), outputAllocationDevice, false));
|
||||
else
|
||||
outputValue = new Value(new NDArrayView(AsDataType<ElementType>(), outputShape, outputAllocationDevice));
|
||||
|
@ -143,7 +143,7 @@ void TestTimesAndPlus(size_t inputDim,
|
|||
// Perform backprop
|
||||
std::vector<ElementType> rootGradientsData(outputShape.TotalSize(), 1);
|
||||
ValuePtr rootGradientValue;
|
||||
if (device.Type() == DeviceType::CPU)
|
||||
if (device.Type() == DeviceKind::CPU)
|
||||
rootGradientValue = new Value(new NDArrayView(outputShape, rootGradientsData.data(), rootGradientsData.size(), device, true));
|
||||
else
|
||||
{
|
||||
|
@ -159,7 +159,7 @@ void TestTimesAndPlus(size_t inputDim,
|
|||
if (usePreAllocatedOutputs)
|
||||
{
|
||||
auto outputAllocationDevice = outputOnSpecifiedDevice ? device : DeviceDescriptor::CPUDevice();
|
||||
if (outputAllocationDevice.Type() == DeviceType::CPU)
|
||||
if (outputAllocationDevice.Type() == DeviceKind::CPU)
|
||||
{
|
||||
plusParameterGradientValue = new Value(new NDArrayView(plusParam.Shape(), plusParameterGradientData.data(), plusParameterGradientData.size(), outputAllocationDevice, false));
|
||||
timesParameterGradientValue = new Value(new NDArrayView(timesParam.Shape(), timesParameterGradientData.data(), timesParameterGradientData.size(), outputAllocationDevice, false));
|
||||
|
@ -181,7 +181,7 @@ void TestTimesAndPlus(size_t inputDim,
|
|||
}
|
||||
|
||||
// Verify forward prop results
|
||||
if (!usePreAllocatedOutputs || (outputOnSpecifiedDevice && (device.Type() != DeviceType::CPU)))
|
||||
if (!usePreAllocatedOutputs || (outputOnSpecifiedDevice && (device.Type() != DeviceKind::CPU)))
|
||||
{
|
||||
NDArrayViewPtr cpuArrayView = new NDArrayView(outputShape, outputData.data(), outputData.size(), DeviceDescriptor::CPUDevice(), false);
|
||||
cpuArrayView->CopyFrom(*outputValue->Data());
|
||||
|
@ -201,7 +201,7 @@ void TestTimesAndPlus(size_t inputDim,
|
|||
FloatingPointVectorCompare(outputData, expectedOutputValues, "TestTimesAndPlus: Forward prop results do not match expected results");
|
||||
|
||||
// Verify backward prop results
|
||||
if (device.Type() != DeviceType::CPU)
|
||||
if (device.Type() != DeviceKind::CPU)
|
||||
{
|
||||
NDArrayViewPtr cpuArrayView = new NDArrayView(AsDataType<ElementType>(), plusParam.Shape(), DeviceDescriptor::CPUDevice());
|
||||
cpuArrayView->CopyFrom(*plusParameterGradientValue->Data());
|
||||
|
@ -236,9 +236,11 @@ void TestTimesAndPlus(size_t inputDim,
|
|||
void FeedForwardTests()
|
||||
{
|
||||
TestTimesAndPlus<double>(4, 2, 5, DeviceDescriptor::CPUDevice(), 3, true, true);
|
||||
#ifndef CPUONLY
|
||||
TestTimesAndPlus<float>(145, 32, 2, DeviceDescriptor::GPUDevice(0), 10, true, false);
|
||||
TestTimesAndPlus<double>(145, 15, 200, DeviceDescriptor::GPUDevice(0), 21, false);
|
||||
|
||||
TestFeedForwardNetworkCreation(DeviceDescriptor::GPUDevice(0));
|
||||
#endif
|
||||
TestFeedForwardNetworkCreation(DeviceDescriptor::CPUDevice());
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ void TestNDArrayView(size_t numAxes, const DeviceDescriptor& device)
|
|||
throw std::runtime_error("The DataBuffer of the NDArrayView does not match the original buffer it was created over");
|
||||
|
||||
NDArrayViewPtr dataView;
|
||||
if ((device.Type() == DeviceType::CPU))
|
||||
if ((device.Type() == DeviceKind::CPU))
|
||||
dataView = cpuDataView;
|
||||
else
|
||||
{
|
||||
|
@ -47,7 +47,7 @@ void TestNDArrayView(size_t numAxes, const DeviceDescriptor& device)
|
|||
ElementType* first = nullptr;
|
||||
const ElementType* second = cpuDataView->DataBuffer<ElementType>();
|
||||
NDArrayViewPtr temp1CpuDataView, temp2CpuDataView;
|
||||
if ((device.Type() == DeviceType::CPU))
|
||||
if ((device.Type() == DeviceKind::CPU))
|
||||
{
|
||||
if (dataView->DataBuffer<ElementType>() != data.data())
|
||||
throw std::runtime_error("The DataBuffer of the NDArrayView does not match the original buffer it was created over");
|
||||
|
@ -69,10 +69,10 @@ void TestNDArrayView(size_t numAxes, const DeviceDescriptor& device)
|
|||
}
|
||||
|
||||
first[0] += 1;
|
||||
if ((device.Type() != DeviceType::CPU))
|
||||
if ((device.Type() != DeviceKind::CPU))
|
||||
clonedView->CopyFrom(*temp1CpuDataView);
|
||||
|
||||
if ((device.Type() == DeviceType::CPU))
|
||||
if ((device.Type() == DeviceKind::CPU))
|
||||
{
|
||||
first = clonedView->WritableDataBuffer<ElementType>();
|
||||
second = dataView->DataBuffer<ElementType>();
|
||||
|
@ -197,10 +197,12 @@ void TestSparseCSCArrayView(size_t numAxes, const DeviceDescriptor& device)
|
|||
void NDArrayViewTests()
|
||||
{
|
||||
TestNDArrayView<float>(2, DeviceDescriptor::CPUDevice());
|
||||
#ifndef CPUONLY
|
||||
TestNDArrayView<float>(0, DeviceDescriptor::GPUDevice(0));
|
||||
TestNDArrayView<double>(4, DeviceDescriptor::GPUDevice(0));
|
||||
|
||||
TestSparseCSCArrayView<float>(1, DeviceDescriptor::GPUDevice(0));
|
||||
TestSparseCSCArrayView<double>(4, DeviceDescriptor::GPUDevice(0));
|
||||
#endif
|
||||
TestSparseCSCArrayView<float>(2, DeviceDescriptor::CPUDevice());
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ void TestRecurrentNetworkCreation(const DeviceDescriptor& device)
|
|||
|
||||
Variable labelsVar = Variable({ numOutputClasses }, AsDataType<ElementType>(), L"Labels");
|
||||
auto trainingLossFunction = CrossEntropyWithSoftmax(classifierOutputFunction, labelsVar, L"lossFunction");
|
||||
auto predictionFunction = PredictionError(classifierOutputFunction, labelsVar, L"predictionError");
|
||||
auto predictionFunction = ClassificationError(classifierOutputFunction, labelsVar, L"predictionError");
|
||||
|
||||
auto LSTMClassifier = Combine({ trainingLossFunction, predictionFunction, classifierOutputFunction }, L"LSTMClassifier");
|
||||
|
||||
|
@ -474,12 +474,18 @@ void TestSimpleRecurrence(size_t inputDim,
|
|||
void RecurrentFunctionTests()
|
||||
{
|
||||
TestSimpleRecurrence<float>(2, 1, 4, 1, DeviceDescriptor::CPUDevice(), 3, false, false);
|
||||
#ifndef CPUONLY
|
||||
TestSimpleRecurrence<double>(11, 9, 16, 7, DeviceDescriptor::GPUDevice(0), 5, true, false);
|
||||
#endif
|
||||
TestSimpleRecurrence<double>(1000, 9, 16, 3, DeviceDescriptor::CPUDevice(), 2, true, true);
|
||||
#ifndef CPUONLY
|
||||
TestSimpleRecurrence<float>(5000, 200, 19, 6, DeviceDescriptor::GPUDevice(0), 3, false, true);
|
||||
TestSimpleRecurrence<double>(1000, 9, 16, 3, DeviceDescriptor::GPUDevice(0), 3, true, true, true);
|
||||
#endif
|
||||
TestSimpleRecurrence<float>(5000, 200, 19, 6, DeviceDescriptor::CPUDevice(), 2, false, true, true);
|
||||
|
||||
#ifndef CPUONLY
|
||||
TestRecurrentNetworkCreation<float>(DeviceDescriptor::GPUDevice(0));
|
||||
#endif
|
||||
TestRecurrentNetworkCreation<double>(DeviceDescriptor::CPUDevice());
|
||||
}
|
||||
|
|
|
@ -81,8 +81,10 @@ void TestTensorPlus(size_t numAxesLeftOperand, size_t numAxesRightOperand, const
|
|||
void TensorTests()
|
||||
{
|
||||
TestTensorPlus<float>(0, 3, DeviceDescriptor::CPUDevice());
|
||||
#ifndef CPUONLY
|
||||
TestTensorPlus<double>(4, 1, DeviceDescriptor::GPUDevice(0));
|
||||
TestTensorPlus<float>(1, 3, DeviceDescriptor::GPUDevice(0));
|
||||
TestTensorPlus<double>(2, 0, DeviceDescriptor::GPUDevice(0));
|
||||
TestTensorPlus<float>(0, 0, DeviceDescriptor::GPUDevice(0));
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -99,6 +99,11 @@
|
|||
<AdditionalDependencies>CNTKLibrary-2.0.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="$(CpuOnlyBuild)">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>CPUONLY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="FeedForwardTests.cpp" />
|
||||
<ClCompile Include="Main.cpp" />
|
||||
|
|
|
@ -6,7 +6,7 @@ Installation on Linux.
|
|||
- If not installed, install Open MPI version 1.10 or later as described at https://github.com/Microsoft/CNTK/wiki/Setup-CNTK-on-Linux#open-mpi
|
||||
- Set the following environment variables (the example below assumes, that CNTK is extracted to /home/username/cntk)
|
||||
export PATH=/home/username/cntk/cntk/bin:$PATH
|
||||
export LD_LIBRARY_PATH=/home/username/cntk/cntk/lib: /home/username/cntk/cntk/dependencies/lib:$LD_LIBRARY_PATH
|
||||
export LD_LIBRARY_PATH=/home/username/cntk/cntk/lib:/home/username/cntk/cntk/dependencies/lib:$LD_LIBRARY_PATH
|
||||
export ACML_FMA=0
|
||||
(ACML_FMA is set to ensure the correct work of ACML library)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ Installation on Linux.
|
|||
- If not installed, install Open MPI version 1.10 or later as described at https://github.com/Microsoft/CNTK/wiki/Setup-CNTK-on-Linux#open-mpi
|
||||
- Set the following environment variables (the example below assumes, that CNTK is extracted to /home/username/cntk)
|
||||
export PATH=/home/username/cntk/cntk/bin:$PATH
|
||||
export LD_LIBRARY_PATH=/home/username/cntk/cntk/lib: /home/username/cntk/cntk/dependencies/lib:$LD_LIBRARY_PATH
|
||||
export LD_LIBRARY_PATH=/home/username/cntk/cntk/lib:/home/username/cntk/cntk/dependencies/lib:$LD_LIBRARY_PATH
|
||||
export ACML_FMA=0
|
||||
(ACML_FMA is set to ensure the correct work of ACML library)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ Installation on Linux.
|
|||
- If not installed, install Open MPI version 1.10 or later as described at https://github.com/Microsoft/CNTK/wiki/Setup-CNTK-on-Linux#open-mpi
|
||||
- Set the following environment variables (the example below assumes, that CNTK is extracted to /home/username/cntk)
|
||||
export PATH=/home/username/cntk/cntk/bin:$PATH
|
||||
export LD_LIBRARY_PATH=/home/username/cntk/cntk/lib: /home/username/cntk/cntk/dependencies/lib:$LD_LIBRARY_PATH
|
||||
export LD_LIBRARY_PATH=/home/username/cntk/cntk/lib:/home/username/cntk/cntk/dependencies/lib:$LD_LIBRARY_PATH
|
||||
export ACML_FMA=0
|
||||
(ACML_FMA is set to ensure the correct work of ACML library)
|
||||
|
||||
|
|
|
@ -106,11 +106,11 @@ fi
|
|||
|
||||
# Dependency files
|
||||
|
||||
# ACML
|
||||
declare -a acmlFiles=("libacml_mp.so" "libiomp5.so")
|
||||
# MKL
|
||||
declare -a mklFiles=("libmkl_cntk_p.so" "libiomp5.so")
|
||||
|
||||
# Open CV
|
||||
declare -a opencvFiles=("libopencv_core.so.3.0" "libopencv_imgproc.so.3.0" "libopencv_imgproc.so.3.0" "libopencv_imgcodecs.so.3.0")
|
||||
declare -a opencvFiles=("libopencv_core.so.3.1" "libopencv_imgproc.so.3.1" "libopencv_imgproc.so.3.1" "libopencv_imgcodecs.so.3.1")
|
||||
|
||||
# libzip
|
||||
declare -a libzipFiles=("libzip.so")
|
||||
|
@ -122,8 +122,8 @@ declare -a cudaFiles=("libcudart.so.7.5" "libcublas.so.7.5" "libcurand.so.7.5" "
|
|||
declare -a cudnnFiles=("libcudnn.so.4")
|
||||
|
||||
# Set dependency sources paths
|
||||
acmlPath="/usr/local/acml5.3.1/ifort64_mp/lib"
|
||||
opencvPath="/usr/local/opencv-3.0.0/lib"
|
||||
mklPath="/usr/local/CNTKCustomMKL/1/x64/parallel"
|
||||
opencvPath="/usr/local/opencv-3.1.0/lib"
|
||||
libzipPath="/usr/local/lib"
|
||||
cudaPath="/usr/local/cuda/lib64"
|
||||
cudnnPath="/usr/local/cudnn-4.0/cuda/lib64"
|
||||
|
@ -143,11 +143,21 @@ mkdir -p $baseBinariesPath
|
|||
# Copy build binaries
|
||||
echo "Copying build binaries..." >&3
|
||||
cp -r $buildPath/* $baseBinariesPath
|
||||
# Remove unnessesary file(s) if exist(s)
|
||||
rm -f $baseBinariesPath/bin/v2librarytests
|
||||
rm -f $baseBinariesPath/bin/cppevalclient
|
||||
rm -f $baseBinariesPath/lib/libcntklibrary-2.0.so
|
||||
|
||||
# Copy Examples
|
||||
echo "Copying Examples..." >&3
|
||||
cp -r Examples $baseDropPath
|
||||
|
||||
# Copy Scripts (Scripts folder from the root of the Repo)
|
||||
echo "Copying Scripts..." >&3
|
||||
cp -r Scripts $baseDropPath
|
||||
# Remove test related file(s) if exist(s)
|
||||
rm -f $baseDropPath/Scripts/pytest.ini
|
||||
|
||||
# Copy Extras
|
||||
echo "Copying Extras..." >&3
|
||||
cp -r $extrasPath/* $baseDropPath
|
||||
|
@ -158,9 +168,9 @@ echo "Copying Dependencies..." >&3
|
|||
# Make dependencies directory
|
||||
mkdir -p $baseDependenciesPath
|
||||
|
||||
# Copy ACML
|
||||
echo "Copying ACML..." >&3
|
||||
CopyFilesFromList $acmlPath acmlFiles[@] $baseDependenciesPath
|
||||
# Copy MKL
|
||||
echo "Copying MKL" >&3
|
||||
CopyFilesFromList $mklPath mklFiles[@] $baseDependenciesPath
|
||||
|
||||
# Copy Open CV
|
||||
echo "Copying Open CV..." >&3
|
||||
|
|
|
@ -74,15 +74,45 @@ Remove-Item $baseDropPath\cntk\*.pdb
|
|||
Remove-Item $baseDropPath\cntk\*.lib
|
||||
Remove-Item $baseDropPath\cntk\*.exp
|
||||
Remove-Item $baseDropPath\cntk\*.metagen
|
||||
# Remove specific items
|
||||
If (Test-Path $baseDropPath\cntk\CNTKLibrary-2.0.dll)
|
||||
{
|
||||
Remove-Item $baseDropPath\cntk\CNTKLibrary-2.0.dll
|
||||
}
|
||||
If (Test-Path $baseDropPath\cntk\CPPEvalClient.exe)
|
||||
{
|
||||
Remove-Item $baseDropPath\cntk\CPPEvalClient.exe
|
||||
}
|
||||
If (Test-Path $baseDropPath\cntk\CSEvalClient.exe)
|
||||
{
|
||||
Remove-Item $baseDropPath\cntk\CSEvalClient.exe
|
||||
}
|
||||
If (Test-Path $baseDropPath\cntk\CSEvalClient.exe.config)
|
||||
{
|
||||
Remove-Item $baseDropPath\cntk\CSEvalClient.exe.config
|
||||
}
|
||||
If (Test-Path $baseDropPath\cntk\CommandEval.exe)
|
||||
{
|
||||
Remove-Item $baseDropPath\cntk\CommandEval.exe
|
||||
}
|
||||
|
||||
# Copy Examples
|
||||
Write-Verbose "Copying Examples ..."
|
||||
Copy-Item Examples -Recurse -Destination $baseDropPath\Examples
|
||||
|
||||
# Copy Scripts
|
||||
Write-Verbose "Copying Scripts ..."
|
||||
Copy-Item Scripts -Recurse -Destination $baseDropPath\Scripts
|
||||
# Remove test related file(s) if exist(s)
|
||||
If (Test-Path $baseDropPath\Scripts\pytest.ini)
|
||||
{
|
||||
Remove-Item $baseDropPath\Scripts\pytest.ini
|
||||
}
|
||||
|
||||
# Copy all items from the share
|
||||
# For whatever reason Copy-Item in the line below does not work
|
||||
# Copy-Item $sharePath"\*" -Recurse -Destination $baseDropPath
|
||||
# Copying with Robocopy. Maximum 2 retries, 30 sec waiting times in between
|
||||
# Copying with Robocopy. Maximum 2 retries, 30 sec waiting time in between
|
||||
Write-Verbose "Copying dependencies and other files from Remote Share ..."
|
||||
robocopy $sharePath $baseDropPath /s /e /r:2 /w:30
|
||||
# Check that Robocopy finished OK.
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
MNIST Example, one hidden layer neural network using training and testing data
|
||||
through files. To generate the data first run fetch_mnist_data.py to fetch the data.
|
||||
Train and Test files obtained need to be converted to CNTKTextFormatReader format using
|
||||
`uci_to_cntk_text_format_converter.py
|
||||
<https://github.com/Microsoft/CNTK/blob/master/Source/Readers/CNTKTextFormatReader/uci_to_cntk_text_format_converter.py>`_
|
||||
`uci2ctf.py
|
||||
<https://github.com/Microsoft/CNTK/blob/master/Scripts/uci2ctf.py>`_
|
||||
Rename train data to Train-28x28_text.txt and test data to Test-28x28_text.txt
|
||||
"""
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ class CNTKTextFormatReader(AbstractReader):
|
|||
with a label.
|
||||
|
||||
If your data is in matrix format (one column per feature), you can use
|
||||
`uci_to_cntk_text_format_converter.py <https://github.com/Microsoft/CNTK/blob/master/Source/Readers/CNTKTextFormatReader/uci_to_cntk_text_format_converter.py>`_
|
||||
`uci2ctf.py <https://github.com/Microsoft/CNTK/blob/master/Scripts/uci2ctf.py>`_
|
||||
to convert it to the CNTKTextFormatReader format.
|
||||
|
||||
Args:
|
||||
|
|
Загрузка…
Ссылка в новой задаче