2using System.Collections.Generic;
24 public class Blob<T> : IDisposable
28 string m_strName =
"";
31 bool m_bIncludeDiff =
true;
32 bool m_bOwnData =
true;
34 bool m_bOwnDiff =
true;
36 bool m_bOwnShape =
true;
40 List<int> m_rgShape =
new List<int>();
44 bool m_bFreezeLearning =
false;
45 bool m_bCpuDataReadyForPush =
false;
46 bool m_bReshapeWhenSharing =
false;
47 bool m_bSnapshotRequested =
false;
48 bool m_bPadded =
false;
49 Dictionary<string, double> m_rgParam =
new Dictionary<string, double>();
50 int[] m_rgShape1 =
new int[4] { 1, 1, 1, 1 };
66 if (bUseHalfSize && typeof(T) != typeof(
float))
71 log.
WriteLine(
"WARNING: Half sizes currently only supported with the 'float' base type - changing back to full size.");
76 m_bIncludeDiff = bIncludeDiff;
98 public Blob(
CudaDnn<T> cuda,
Log log,
int nNum,
int nChannels,
int nHeight,
int nWidth,
bool bIncludeDiff =
true,
bool bUseHalfSize =
false)
99 : this(cuda, log, bIncludeDiff, bUseHalfSize)
103 Reshape(nNum, nChannels, nHeight, nWidth);
115 public Blob(
CudaDnn<T> cuda,
Log log, List<int> rgShape,
bool bIncludeDiff =
true,
bool bUseHalfSize =
false)
116 : this(cuda, log, bIncludeDiff, bUseHalfSize)
131 public Blob(
CudaDnn<T> cuda,
Log log,
int[] rgShape,
bool bIncludeDiff =
true,
bool bUseHalfSize =
false)
132 : this(cuda, log, bIncludeDiff, bUseHalfSize)
147 : this(cuda, log, (b.m_diff != null) ? true : false, bUseHalfSize)
164 : this(cuda, log, bIncludeDiff, bUseHalfSize)
177 : this(cuda, log, true, bUseHalfSize)
189 : this(blob.
Cuda, blob.
Log, blob.m_bIncludeDiff)
206 for (
int i = rgShape.Count; i < 4; i++)
222 if (m_rgParam.ContainsKey(strName))
223 return m_rgParam[strName];
235 if (!m_rgParam.ContainsKey(strName))
236 m_rgParam.Add(strName, dfVal);
238 m_rgParam[strName] = dfVal;
247 foreach (KeyValuePair<string, double> kv
in b.m_rgParam)
249 if (!m_rgParam.ContainsKey(kv.Key))
250 m_rgParam.Add(kv.Key, kv.Value);
252 m_rgParam[kv.Key] = kv.Value;
261 get {
return (T)Convert.ChangeType(0, typeof(T)); }
269 get {
return (T)Convert.ChangeType(1, typeof(T)); }
277 get {
return (T)Convert.ChangeType(-1, typeof(T)); }
285 get {
return m_bPadded; }
286 set { m_bPadded = value; }
306 public void ConvertToHalf(
long hWorkMem, ulong lWorkSize,
bool bData,
bool bDiff)
308 int nCount =
count();
309 ulong lSize = (ulong)nCount * 2 *
CudaDnn<T>.basetype_size(
true);
312 throw new Exception(
"Memory out of range!");
314 if (lWorkSize < lSize)
315 throw new Exception(
"Work memory is not large enough!");
318 m_cuda.
copy(nCount,
gpu_data, hWorkMem, 0, 0, -1,
null,
true);
321 m_cuda.
copy(nCount,
gpu_diff, hWorkMem, 0, nCount, -1,
null,
true);
339 public void ConvertToBase(
long hWorkMem, ulong lWorkSize,
bool bData,
bool bDiff)
341 int nCount =
count();
342 ulong lSize = (ulong)nCount * 2 *
CudaDnn<T>.basetype_size(
false);
345 throw new Exception(
"Memory out of range!");
347 if (lWorkSize < lSize)
348 throw new Exception(
"Work memory is not large enough!");
351 m_cuda.
copy(nCount,
gpu_data, hWorkMem, 0, 0, -1,
null,
false);
354 m_cuda.
copy(nCount,
gpu_diff, hWorkMem, 0, nCount, -1,
null,
false);
378 get {
return m_bFreezeLearning; }
379 set { m_bFreezeLearning = value; }
387 get {
return m_cuda; }
395 get {
return m_log; }
402 protected virtual void Dispose(
bool bDisposing)
442 public void Reshape(
int nNum,
int nChannels,
int nHeight,
int nWidth,
bool? bUseHalfSize =
null)
444 m_rgShape1[0] = nNum;
445 m_rgShape1[1] = nChannels;
446 m_rgShape1[2] = nHeight;
447 m_rgShape1[3] = nWidth;
449 Reshape(m_rgShape1, bUseHalfSize);
452 private string toString(List<int> rgShape)
454 return toString(rgShape.ToArray());
457 private string toString(
int[] rgShape)
461 for (
int i = 0; i < rgShape.Length; i++)
463 str += rgShape[i].ToString();
467 str = str.TrimEnd(
' ',
',');
473 private void reshapeShape(List<int> rgShape)
475 reshapeShape(rgShape.ToArray());
478 private void reshapeShape(
int[] rgShape)
483 m_rgShape =
new List<int>();
486 m_shape =
new SyncedMemory<T>(m_cuda, m_log, rgShape.Length);
487 else if (m_shape.
Capacity < rgShape.Length)
489 else if (m_shape.
Count != rgShape.Length)
491 m_shape.
Count = rgShape.Length;
495 if (rgShape.Length > 0)
499 if (rgShapeData ==
null || rgShapeData.Length != rgShape.Length)
503 if (rgShapeData ==
null || rgShapeData.Length != rgShape.Length)
504 rgShapeData =
new T[rgShape.Length];
509 for (
int i = 0; i < rgShape.Length; i++)
513 string strBlobName = (!
string.IsNullOrEmpty(m_strName)) ?
"Blob '" + m_strName +
"': " :
"";
514 m_log.
FAIL(strBlobName +
"The shape value at " + i.ToString() +
" of shape " + toString(rgShape) +
" must be >= 0.");
519 if (rgShape[i] >
int.MaxValue / m_nCount)
521 string strBlobName = (!
string.IsNullOrEmpty(m_strName)) ?
"Blob '" + m_strName +
"': " :
"";
522 m_log.
FAIL(strBlobName +
"The blob size at item " + i.ToString() +
" of shape " + toString(rgShape) +
" exceeds the maximum of " + (
int.MaxValue / m_nCount).
ToString() +
"!");
526 m_nCount *= rgShape[i];
527 m_rgShape.Add(rgShape[i]);
529 int nShape = (int)(
double)Convert.ChangeType(rgShapeData[i], typeof(
double));
531 if (nShape != rgShape[i])
533 rgShapeData[i] = (T)Convert.ChangeType(rgShape[i], typeof(T));
562 public void Reshape(List<int> rgShape,
bool? bUseHalfSize =
null)
564 Reshape(rgShape.ToArray(), bUseHalfSize);
583 public void Reshape(
int[] rgShape,
bool? bUseHalfSize =
null)
585 reshapeShape(rgShape);
587 if (m_nCount > m_nCapacity || (m_data !=
null && m_nCount > m_data.
Capacity) || (m_diff !=
null && m_nCount > m_diff.
Capacity) || (m_data !=
null && bUseHalfSize.HasValue && m_data.
HalfSize != bUseHalfSize.Value))
595 m_nCapacity = m_nCount;
598 m_data =
new SyncedMemory<T>(m_cuda, m_log, m_nCapacity,
null, bUseHalfSize.GetValueOrDefault(
false));
600 m_data.
Allocate(m_nCapacity, bUseHalfSize.GetValueOrDefault(m_data.
HalfSize));
605 m_diff =
new SyncedMemory<T>(m_cuda, m_log, m_nCapacity,
null, bUseHalfSize.GetValueOrDefault(
false));
607 m_diff.
Allocate(m_nCapacity, bUseHalfSize.GetValueOrDefault(m_data.
HalfSize));
611 if (m_data.
Count != m_nCount)
612 m_data.
Count = m_nCount;
616 if (m_diff.
Count != m_nCount)
617 m_diff.
Count = m_nCount;
662 for (
int i = 0; i < m_rgShape.Count; i++)
664 strOut += m_rgShape[i].ToString() +
" ";
667 strOut +=
"(" + m_rgShape.Count.ToString() +
")";
677 get {
return m_bIncludeDiff; }
708 return m_rgShape.Count;
722 for (
int i = m_rgShape.Count - 1; i >= 0; i--)
724 if (bCount || m_rgShape[i] != 1)
751 public int count(
int nStartIdx,
int nEndIdx)
753 m_log.
CHECK_LE(nStartIdx, nEndIdx,
"The start idx must be <= the end idx.");
754 m_log.
CHECK_GE(nStartIdx, 0,
"The start idx must be >= 0.");
755 m_log.
CHECK_GE(nEndIdx, 0,
"The end idx must be >= 0.");
756 m_log.
CHECK_LE(nStartIdx,
num_axes,
"The start axis must be <= the number of axes.");
757 m_log.
CHECK_LE(nEndIdx,
num_axes,
"The end axis must be <= the number of axes.");
827 m_log.
CHECK_LE(
num_axes, 4,
"Cannot use legacy accessors on Blobs with > 4 axes.");
828 m_log.
CHECK_LT(nIdx, 4,
"The index must be less than 4.");
829 m_log.
CHECK_GE(nIdx, -4,
"The index must be greater than or equal to -4.");
850 public int offset(
int n,
int c = 0,
int h = 0,
int w = 0)
856 m_log.
CHECK_GE(n, 0,
"n must be >= 0.");
858 m_log.
CHECK_GE(c1, 0,
"channels must be >= 0.");
859 m_log.
CHECK_LE(c, c1,
"c must be <= channels.");
860 m_log.
CHECK_GE(h1, 0,
"height must be >= 0.");
861 m_log.
CHECK_LE(h, h1,
"w must be <= height.");
862 m_log.
CHECK_GE(w1, 0,
"width must be >= 0.");
863 m_log.
CHECK_LE(w, w1,
"w must be <= width.");
865 return ((n * c1 + c) * h1 + h) * w1 + w;
875 m_log.
CHECK_LE(rgIdx.Count,
num_axes,
"The index array must have an item count <= num_axes.");
885 m_log.
CHECK_GE(rgIdx[i], 0,
"The index at " + i.ToString() +
" must be >= 0.");
886 m_log.
CHECK_LT(rgIdx[i],
shape(i),
"The index at " + i.ToString() +
" must be <= the shape at " + i.ToString());
903 public void CopyFrom(
Blob<T> src,
int nSrcOffset,
int nDstOffset,
int nCount,
bool bCopyData,
bool bCopyDiff)
905 m_log.
CHECK_GE(
count(), nDstOffset + nCount,
"The data to be copied is larger that the destination blob.");
906 m_log.
CHECK_GE(src.
count(), nSrcOffset + nCount,
"The data to be copied is larger than the source blob.");
928 public long CopyFrom(
Blob<T> src,
bool bCopyDiff =
false,
bool bReshape =
false,
long hDstHostBuffer = 0,
bool bIgnoreShape =
false)
947 m_log.
FAIL(
"Trying to copy blobs of different sizes!");
953 return hDstHostBuffer;
955 return m_diff.
Copy(src.
diff, hDstHostBuffer);
960 return hDstHostBuffer;
962 return m_data.
Copy(src.
data, hDstHostBuffer);
982 m_log.
FAIL(
"The destination blob must be larger than the source blob.");
1004 m_log.
CHECK_EQ(blobSrc.
num_axes, 4,
"Currently, Blobs only support transposing 4 axis tensors.");
1025 for (
int n = 0; n < nN; n++)
1027 for (
int c = 0; c < nC; c++)
1029 int nOffset = (n * nC * nH * nW) + (c * nH * nW);
1031 for (
int h = 0; h < nH; h++)
1033 for (
int w = 0; w < nW; w++)
1035 int nSrcIdx = nOffset + (h * nW) + w;
1036 int nDstIdx = nOffset + (w + nH) + h;
1037 rgDst[nDstIdx] = rgSrc[nSrcIdx];
1054 public void CopyFrom(
Blob<T> blobSrc,
int nChannelFrom,
int nChannelTo,
bool bCopyDiff =
false)
1056 m_log.
CHECK_EQ(blobSrc.
num,
num,
"The source and destination blobs must have the same num.");
1057 m_log.
CHECK_EQ(blobSrc.
height,
height,
"The source and destination blobs must have the same height.");
1058 m_log.
CHECK_EQ(blobSrc.
width,
width,
"The source and destination blobs must have the same width.");
1059 m_log.
CHECK_LT(nChannelFrom, blobSrc.
channels,
"The channel form parameter is out of range!");
1060 m_log.
CHECK_LT(nChannelTo,
channels,
"The channel to parameter is out of range!");
1068 int nSrcOffset = nChannelFrom * nDim;
1069 int nDstOffset = nChannelTo * nDim;
1070 int nSrcStep = (nCsrc * nDim);
1071 int nDstStep = (nCdst * nDim);
1073 for (
int n = 0; n <
num; n++)
1076 nSrcOffset += nSrcStep;
1077 nDstOffset += nDstStep;
1093 public bool Compare(
Blob<T> other,
Blob<T> work,
bool bDiff =
false,
double dfTol = 1e-8,
bool bZeroCheck =
true,
bool bFullCompare =
false,
bool bDetectNans =
true,
bool bForceOtherData =
false)
1097 return CompareEx(other, work, out dfMin, out dfMax, bDiff, dfTol, bZeroCheck, bFullCompare, bDetectNans, bForceOtherData);
1114 public bool CompareEx(
Blob<T> other,
Blob<T> work, out
double dfMin, out
double dfMax,
bool bDiff =
false,
double dfTol = 1e-8,
bool bZeroCheck =
true,
bool bFullCompare =
false,
bool bDetectNans =
true,
bool bForceOtherData =
false)
1119 int nCount =
count();
1120 if (nCount != other.
count())
1126 if (
Cuda.KernelHandle != other.
Cuda.KernelHandle)
1127 throw new Exception(
"The compare blob has a different Cuda Kernel Handles!");
1129 if (
Cuda.KernelHandle != work.
Cuda.KernelHandle)
1130 throw new Exception(
"The work blob has a different Cuda Kernel Handle!");
1142 if (Math.Abs(dfMin) > dfTol)
1150 Tuple<double, double, double, double> minmax1 = m_cuda.
minmax(nCount, h1, work.
gpu_data, work.
gpu_diff,
true);
1151 if (minmax1.Item3 > 0 || minmax1.Item4 > 0)
1154 Tuple<double, double, double, double> minmax2 = m_cuda.
minmax(nCount, h2, work.
gpu_data, work.
gpu_diff,
true);
1155 if (minmax2.Item3 > 0 || minmax2.Item4 > 0)
1164 if ((dfZero1 == 0 && dfZero2 != 0) || (dfZero1 != 0 && dfZero2 == 0))
1172 Dictionary<int, float> rgErr =
new Dictionary<int, float>();
1174 for (
int i = 0; i < rgf1.Length; i++)
1178 float fDiff = Math.Abs(f1 - f2);
1181 rgErr.Add(i, fDiff);
1184 if (rgErr.Count > 0)
1199 int nCount =
count();
1204 Tuple<double, double, double, double> minmax1 = m_cuda.
minmax(nCount, h1, work.
gpu_data, work.
gpu_diff,
true);
1205 if (minmax1.Item3 > 0 || minmax1.Item4 > 0)
1231 if (Math.Abs(dfMin) > dfTol)
1241#pragma warning disable 1591
1243 public void KeepBestResultsByChannel(
int nNumberToKeep)
1245 m_log.
CHECK_EQ(
num_axes, 4,
"Currently KeepBestResutls only works on 4-axis blobs.");
1252 List<List<KeyValuePair<int, float>>> rgrgKeyValues =
new List<List<KeyValuePair<int, float>>>();
1253 List<List<List<List<float>>>> rgrgrgrgData =
new List<List<List<List<float>>>>();
1255 for (
int n = 0; n < nN; n++)
1257 List<KeyValuePair<int, float>> rgKeyValues =
new List<KeyValuePair<int, float>>();
1258 List<List<List<float>>> rgrgrgData =
new List<List<List<float>>>();
1260 for (
int c = 0; c < nC; c++)
1263 List<List<float>> rgrgData =
new List<List<float>>();
1265 for (
int h = 0; h < nH; h++)
1267 List<float> rgVal =
new List<float>();
1269 for (
int w = 0; w < nW; w++)
1271 int nIdx = (n * nC * nH * nW) + (c * nH * nW) + (h * nW) + w;
1272 float fVal = (float)Convert.ChangeType(rgData[nIdx], typeof(
float));
1277 rgrgData.Add(rgVal);
1280 rgKeyValues.Add(
new KeyValuePair<int, float>(c, fSum));
1281 rgrgrgData.Add(rgrgData);
1284 rgKeyValues.Sort(
new Comparison<KeyValuePair<int, float>>(sort));
1286 rgrgKeyValues.Add(rgKeyValues);
1287 rgrgrgrgData.Add(rgrgrgData);
1293 for (
int n = 0; n < nN; n++)
1295 List<KeyValuePair<int, float>> rgKeyValues = rgrgKeyValues[n];
1296 List<List<List<float>>> rgrgrgData = rgrgrgrgData[n];
1297 List<int> rgIdx =
new List<int>();
1299 for (
int i = 0; i < nNumberToKeep && i < rgKeyValues.Count; i++)
1301 rgIdx.Add(rgKeyValues[i].Key);
1304 foreach (
int c
in rgIdx)
1306 List<List<float>> rgrgData = rgrgrgData[c];
1308 for (
int h = 0; h < nH; h++)
1310 List<float> rgVal = rgrgData[h];
1312 for (
int w = 0; w < nW; w++)
1314 int nIdx = (n * nC * nH * nW) + (c * nH * nW) + (h * nW) + w;
1315 rgData[nIdx] = (T)Convert.ChangeType(rgVal[w], typeof(T));
1324 public void KeepBestResultsByWeight(
int nNumberToKeep)
1326 m_log.
CHECK_EQ(
num_axes, 4,
"Currently KeepBestResutls only works on 4-axis blobs.");
1333 List<List<KeyValuePair<int, float>>> rgrgKeyValues =
new List<List<KeyValuePair<int, float>>>();
1335 for (
int n = 0; n < nN; n++)
1337 List<KeyValuePair<int, float>> rgKeyValues =
new List<KeyValuePair<int, float>>();
1339 for (
int c = 0; c < nC; c++)
1341 for (
int h = 0; h < nH; h++)
1343 for (
int w = 0; w < nW; w++)
1345 int nIdx = (n * nC * nH * nW) + (c * nH * nW) + (h * nW) + w;
1346 rgKeyValues.Add(
new KeyValuePair<int, float>(nIdx, (
float)Convert.ChangeType(rgData[nIdx], typeof(
float))));
1351 rgKeyValues.Sort(
new Comparison<KeyValuePair<int, float>>(sort));
1352 rgrgKeyValues.Add(rgKeyValues);
1358 for (
int n = 0; n < nN; n++)
1360 List<KeyValuePair<int, float>> rgKeyValues = rgrgKeyValues[n];
1362 for (
int i = 0; i < nNumberToKeep && i < rgKeyValues.Count; i++)
1364 KeyValuePair<int, float> kv = rgKeyValues[i];
1365 rgData[kv.Key] = (T)Convert.ChangeType(kv.Value, typeof(T));
1372#pragma warning restore 1591
1375 private int sort(KeyValuePair<int, float> a, KeyValuePair<int, float> b)
1377 if (a.Value < b.Value)
1380 if (a.Value > b.Value)
1437 get {
return m_data; }
1445 get {
return m_diff; }
1577 if (!m_bIncludeDiff || m_bFreezeLearning)
1593 List<int> rgShape =
new List<int>();
1599 if (bp.
num.HasValue)
1600 rgShape.Add(bp.
num.Value);
1606 rgShape.Add(bp.
height.Value);
1608 if (bp.
width.HasValue)
1609 rgShape.Add(bp.
width.Value);
1628 m_log.
CHECK_EQ(m_nCount, bp.
double_data.Count,
"The double data count is not the same as the blob data count!");
1631 else if (bp.
data.Count > 0)
1633 m_log.
CHECK_EQ(m_nCount, bp.
data.Count,
"The double data count is not the same as the blob data count!");
1645 m_log.
CHECK_EQ(m_nCount, bp.
double_diff.Count,
"The double diff count is not the same as the blob data count!");
1648 else if (bp.
diff.Count > 0)
1650 m_log.
CHECK_EQ(m_nCount, bp.
diff.Count,
"The double data count is not the same as the blob data count!");
1670 if (typeof(T) == typeof(
double))
1688 float[] rgDataF =
Utility.ConvertVecF<T>(rgData);
1689 bp.
data =
new List<float>(rgDataF);
1694 float[] rgDiffF =
Utility.ConvertVecF<T>(rgDiff);
1695 bp.
diff =
new List<float>(rgDiffF);
1708 if (m_nCount == 0 ||
gpu_data == 0)
1720 if (m_nCount == 0 ||
gpu_diff == 0)
1732 if (m_nCount == 0 ||
gpu_data == 0)
1744 if (m_nCount == 0 ||
gpu_diff == 0)
1756 scale_data((T)Convert.ChangeType(df, typeof(T)));
1765 scale_diff((T)Convert.ChangeType(df, typeof(T)));
1804 get {
return m_bReshapeWhenSharing; }
1805 set { m_bReshapeWhenSharing = value; }
1815 if (!m_bReshapeWhenSharing)
1816 m_log.
CHECK_EQ(m_nCount, b.
count(),
"The blob counts are not the same!");
1818 reshapeShape(b.
shape());
1820 if (m_bOwnData && m_data !=
null)
1834 if (!m_bReshapeWhenSharing)
1835 m_log.
CHECK_EQ(m_nCount, b.
count(),
"The blob counts are not the same!");
1837 reshapeShape(b.
shape());
1839 if (m_bOwnDiff && m_diff !=
null)
1852 if (m_bOwnData && m_data !=
null)
1858 if (m_bOwnDiff && m_diff !=
null)
1864 if (m_bOwnShape && m_shape !=
null)
1867 m_shape = b.m_shape;
1868 m_bOwnShape =
false;
1870 m_nCount = b.m_nCount;
1871 m_nCapacity = b.m_nCapacity;
1872 m_rgShape = b.m_rgShape;
1884 get {
return m_bSnapshotRequested; }
1885 set { m_bSnapshotRequested = value; }
1897 throw new Exception(
"No data at index = " + nIdx.ToString());
1911 throw new Exception(
"No data at index = " + nIdx.ToString());
1922 public void SetData(T[] rgData,
int nCount = -1,
bool bSetCount =
true)
1924 m_data.
SetData(rgData, nCount, bSetCount);
1961 public void SetData(
double dfVal,
int nStartIdx,
int nCount)
1963 T tVal = (T)Convert.ChangeType(dfVal, typeof(T));
1966 for (
int i = 0; i < nCount; i++)
1968 if (nStartIdx + i < rg.Length)
1969 rg[nStartIdx + i] = tVal;
1998 public void SetDiff(
double dfVal,
int nStartIdx,
int nCount)
2000 T tVal = (T)Convert.ChangeType(dfVal, typeof(T));
2003 for (
int i = 0; i < nCount; i++)
2005 if (nStartIdx + i < rg.Length)
2006 rg[nStartIdx + i] = tVal;
2018 public void SetDiff(T[] rgDiff,
int nCount = -1,
bool bSetCount =
true)
2020 m_diff.
SetData(rgDiff, nCount, bSetCount);
2037 T[] rgData = d.GetData<T>();
2039 m_log.
CHECK_EQ(rgData.Length,
count(),
"The datum data length of " + rgData.Length.ToString() +
" should be equal to the Blob count() of " +
count().ToString());
2054 m_bCpuDataReadyForPush =
true;
2064 if (!m_bCpuDataReadyForPush)
2068 throw new Exception(
"There is no CPU data to push to the GPU!");
2071 m_bCpuDataReadyForPush =
false;
2089 if (m_rgShape.Count <= 4 &&
2108 public bool CompareShape(List<int> rgShape,
bool bCompareCpuDataLen =
false)
2115 if (
shape().Count == 0 && rgShape.Count == 0)
2118 if (
shape().Count == 0 && rgShape.Count == 1 && rgShape[0] == 0)
2121 List<int> rgShape1 =
new List<int>(
shape());
2122 while (rgShape1.Count < rgShape.Count)
2127 if (bCompareCpuDataLen)
2130 for (
int i = 0; i < rgShape.Count; i++)
2132 nCount *= rgShape[i];
2139 return Utility.Compare<
int>(rgShape1, rgShape);
2150 return CompareShape(
new List<int>(rgShape), bCompareCpuDataLen);
2168 if (typeof(T) == typeof(
double))
2185 get {
return m_strName; }
2191 m_data.
Tag = m_strName +
" data";
2194 m_diff.
Tag = m_strName +
" diff";
2209 b.m_diff.Copy(m_diff);
2211 b.m_data.Copy(m_data);
2231 if ((
double)Convert.ChangeType(fScale, typeof(
double)) != 1.0)
2268 double dfVal = 1.0/(double)Convert.ChangeType(fScale, typeof(
double));
2282 public void SaveBinary(
string strFile,
bool bData,
bool bDiff,
bool bIncludeName =
true)
2284 using (FileStream fs = File.OpenWrite(strFile))
2285 using (BinaryWriter bw =
new BinaryWriter(fs))
2287 Save(bw, bData, bDiff, bIncludeName);
2298 public void Save(BinaryWriter bw,
bool bData,
bool bDiff,
bool bIncludeName =
true)
2306 bw.Write(m_strName.Length);
2307 bw.Write(m_strName);
2310 bw.Write(m_rgShape.Count);
2311 for (
int i = 0; i < m_rgShape.Count; i++)
2313 bw.Write(m_rgShape[i]);
2324 foreach (
double dfVal
in rgdfData)
2340 foreach (
double dfVal
in rgdfDiff)
2361 using (FileStream fs = File.OpenRead(strFile))
2362 using (BinaryReader br =
new BinaryReader(fs))
2364 return Load(cuda, log, br, bData, bDiff);
2381 int nNameLen = br.ReadInt32();
2383 b.
Name = br.ReadString();
2385 List<int> rgShape =
new List<int>();
2386 int nCount = br.ReadInt32();
2388 for (
int i = 0; i < nCount; i++)
2390 rgShape.Add(br.ReadInt32());
2395 int nItemCount = br.ReadInt32();
2396 int nDataCount = br.ReadInt32();
2398 if (nDataCount > nItemCount)
2399 throw new Exception(
"Invalid data count read!");
2401 List<double> rgData =
new List<double>();
2403 for (
int i = 0; i < nDataCount; i++)
2405 rgData.Add(br.ReadDouble());
2408 int nDiffCount = br.ReadInt32();
2410 if (nDiffCount > nItemCount)
2411 throw new Exception(
"Invalid diff count read!");
2413 List<double> rgDiff =
new List<double>();
2415 for (
int i = 0; i < nDiffCount; i++)
2417 rgDiff.Add(br.ReadDouble());
2420 if (nDataCount > 0 && nDiffCount > 0 && nDataCount != nDiffCount)
2421 throw new Exception(
"Invalid diff and data counts read - they should be equal!");
2423 if (bData && rgData.Count > 0)
2426 if (bDiff && rgDiff.Count > 0)
2438 using (MemoryStream ms =
new MemoryStream())
2439 using (BinaryWriter bw =
new BinaryWriter(ms))
2441 Save(bw,
true,
false,
true);
2442 return ms.ToArray();
2455 using (MemoryStream ms =
new MemoryStream(rg))
2456 using (BinaryReader br =
new BinaryReader(ms))
2458 return Load(cuda, log, br,
true,
true);
2468 string strSize = (
HalfSize) ?
"HALF " :
"FULL ";
2469 return strSize + m_strName +
" (" +
shape_string +
")";
2483 for (
int i = 0; i < rg.Length && i < nMax; i++)
2485 str += rg[i].ToString(
"N4");
2489 str = str.TrimEnd(
',');
2599 private int get_index_up_to(List<int> rgShape,
int nMax = 12800)
2601 int nIndexUpTo = m_rgShape.Count - 1;
2602 int nNum = m_rgShape[nIndexUpTo];
2604 while (nIndexUpTo > 0 && nNum < nMax)
2606 nNum *= m_rgShape[nIndexUpTo-1];
2611 if (nNum > 1 && nIndexUpTo == 0 && m_rgShape.Count > 1)
2624 public Tuple<double, double, double, double>
minmax_data(
Blob<T> work,
bool bDetectNans =
false,
bool bUseChunks =
false)
2626 int nCount =
count();
2629 return new Tuple<double, double, double, double>(0, 0, 0, 0);
2634 return new Tuple<double, double, double, double>(rgdf[0], rgdf[0],
double.IsNaN(rgdf[0]) ? 1 : 0,
double.IsInfinity(rgdf[0]) ? 1 : 0);
2637 work.
Reshape(nCount + 64, 1, 1, 1);
2640 int nIndexUpTo = get_index_up_to(m_rgShape);
2641 if (nIndexUpTo == 0 || nIndexUpTo >= m_rgShape.Count || !bUseChunks)
2644 List<double> rgdfMax =
new List<double>();
2645 List<double> rgdfMin =
new List<double>();
2646 List<double> rgdfItem3 =
new List<double>();
2647 List<double> rgdfItem4 =
new List<double>();
2648 List<int> rgShape =
new List<int>();
2651 for (
int i = 0; i < m_rgShape.Count; i++)
2655 nNum *= m_rgShape[i];
2660 rgShape.Add(m_rgShape[i]);
2666 for (
int i = 0; i < nNum; i++)
2668 nCount = item.
count();
2671 rgdfMin.Add(minmax.Item1);
2672 rgdfMax.Add(minmax.Item2);
2673 rgdfItem3.Add(minmax.Item3);
2674 rgdfItem4.Add(minmax.Item4);
2679 double dfMin = rgdfMin.Min(p => p);
2680 double dfMax = rgdfMax.Max(p => p);
2681 double dfItem3 = rgdfItem3.Sum(p => p);
2682 double dfItem4 = rgdfItem4.Sum(p => p);
2684 return new Tuple<double, double, double, double>(dfMin, dfMax, dfItem3, dfItem4);
2694 public Tuple<double, double, double, double>
minmax_diff(
Blob<T> work,
bool bDetectNans =
false,
bool bUseChunks =
false)
2696 int nCount =
count();
2699 return new Tuple<double, double, double, double>(0, 0, 0, 0);
2704 return new Tuple<double, double, double, double>(rgdf[0], rgdf[0],
double.IsNaN(rgdf[0]) ? 1 : 0,
double.IsInfinity(rgdf[0]) ? 1 : 0);
2707 work.
Reshape(nCount + 64, 1, 1, 1);
2710 int nIndexUpTo = get_index_up_to(m_rgShape);
2711 if (nIndexUpTo == 0 || nIndexUpTo >= m_rgShape.Count || !bUseChunks)
2714 List<double> rgdfMax =
new List<double>();
2715 List<double> rgdfMin =
new List<double>();
2716 List<double> rgdfItem3 =
new List<double>();
2717 List<double> rgdfItem4 =
new List<double>();
2718 List<int> rgShape =
new List<int>();
2721 for (
int i = 0; i < m_rgShape.Count; i++)
2725 nNum *= m_rgShape[i];
2730 rgShape.Add(m_rgShape[i]);
2736 for (
int i = 0; i < nNum; i++)
2738 nCount = item.
count();
2741 rgdfMin.Add(minmax.Item1);
2742 rgdfMax.Add(minmax.Item2);
2743 rgdfItem3.Add(minmax.Item3);
2744 rgdfItem4.Add(minmax.Item4);
2749 double dfMin = rgdfMin.Min(p => p);
2750 double dfMax = rgdfMax.Max(p => p);
2751 double dfItem3 = rgdfItem3.Sum(p => p);
2752 double dfItem4 = rgdfItem4.Sum(p => p);
2754 return new Tuple<double, double, double, double>(dfMin, dfMax, dfItem3, dfItem4);
2762 get {
return m_type; }
2763 set { m_type = value; }
2771 get {
return m_tag; }
2772 set { m_tag = value; }
2784#pragma warning disable 1591
2786 public void rollaxis()
2793 public void save_images(
string strPath, Blob<T> blobLabels,
double dfScale)
2795 if (!Directory.Exists(strPath))
2796 Directory.CreateDirectory(strPath);
2798 T[] rgLabels = blobLabels.update_cpu_data();
2803 for (
int i = 0; i < rgData.Length; i++)
2805 double dfVal =
Utility.ConvertVal<T>(rgData[i]);
2817 rgData[i] =
Utility.ConvertVal<T>(dfVal);
2822 strPath = strPath.TrimEnd(
'\\');
2826 for (
int n = 0; n <
num; n++)
2828 int nIdx = n * nCount;
2832 int nLabel = (int)(
float)Convert.ChangeType(rgLabels[n], typeof(
float));
2834 string strName = strPath +
"\\img_" + n.ToString() +
"_label_" + nLabel.ToString() +
".png";
2835 img.Save(strName,
System.Drawing.Imaging.ImageFormat.Png);
2841#pragma warning restore 1591
2854 m_log.
CHECK_EQ(
num_axes, rgShape.Count,
"When resizing, the new shape must have the same number of axes as the blob to be resized.");
2856 m_log.
CHECK_EQ(
num, rgShape[0],
"Resizing only allowed on the last two axes.");
2857 m_log.
CHECK_EQ(
channels, rgShape[1],
"Resizing only allowed on the last two axes.");
2860 float[] rgDataF =
Utility.ConvertVecF<T>(rgData);
2863 newBlob.Reshape(rgShape);
2865 T[] rgDataNew = newBlob.mutable_cpu_data;
2866 float[] rgDataNewF =
Utility.ConvertVecF<T>(rgDataNew);
2870 for (
int n = 0; n <
num; n++)
2874 float fMin =
float.MaxValue;
2875 float fMax = -
float.MaxValue;
2878 int nSize = nH * nW;
2880 for (
int y = 0; y < nH; y++)
2882 for (
int x = 0; x < nW; x++)
2884 int nIdx = n * (
channels * nSize) + c * nSize + y * nW + x;
2885 float fVal = rgDataF[nIdx];
2895 for (
int y = 0; y < nH; y++)
2897 for (
int x = 0; x < nW; x++)
2899 int nIdx = n * (
channels * nSize) + c * nSize + y * nW + x;
2900 float fVal = rgDataF[nIdx];
2902 fVal = ((fVal - fMin) / (fMax - fMin)) * 255.0f;
2904 bmp.SetPixel(x, y, Color.FromArgb((
int)fVal, (int)fVal, (
int)fVal));
2910 nH = newBlob.height;
2914 for (
int y = 0; y < nH; y++)
2916 for (
int x = 0; x < nW; x++)
2918 int nIdx = n * (
channels * nSize) + c * nSize + y * nW + x;
2920 Color clr = bmpNew.GetPixel(x, y);
2921 float fVal = ((clr.R / 255.0f) * (fMax - fMin)) + fMin;
2923 rgDataNewF[nIdx] = fVal;
2944 if (!dfMean.HasValue || !dfStd.HasValue)
2949 dfStd =
std(dfMean.Value, rgF);
2952 if (dfMean.Value != 0)
2955 if (dfStd.Value != 0 && dfStd.Value != 1.0)
2965 public double mean(
float[] rgDf =
null,
bool bDiff =
false)
2972 for (
int i = 0; i < rgDf.Length; i++)
2977 return dfSum / rgDf.Length;
2986 public double sum(
float[] rgDf =
null,
bool bDiff =
false)
2993 for (
int i = 0; i < rgDf.Length; i++)
3007 public double std(
double? dfMean =
null,
float[] rgDf =
null)
3014 if (!dfMean.HasValue)
3015 dfMean =
mean(rgDf);
3017 for (
int i = 0; i < rgDf.Length; i++)
3019 dfSum += Math.Pow(rgDf[i] - dfMean.Value, 2);
3022 return Math.Sqrt(dfSum / rgDf.Length);
3038 int nIdxR = nY *
width + nX;
3039 int nIdxG = nDim + nIdxR;
3040 int nIdxB = nDim + nDim + nIdxR;
3049 T fR =
Utility.ConvertVal<T>((double)R);
3050 T fG =
Utility.ConvertVal<T>((double)G);
3051 T fB =
Utility.ConvertVal<T>((double)B);
3053 T[] rg = m_cuda.
SetPixel(
mutable_gpu_data,
count(),
true, 0,
new Tuple<int, T>(nIdxR, fR),
new Tuple<int, T>(nIdxG, fG),
new Tuple<int, T>(nIdxB, fB));
3055 return new Tuple<T, T, T>(rg[0], rg[1], rg[2]);
3071 int nIdxR = nY *
width + nX;
3072 int nIdxG = nDim + nIdxR;
3073 int nIdxB = nDim + nDim + nIdxR;
3086 if (bReturnOriginal)
3088 T[] rg = m_cuda.
SetPixel(
mutable_gpu_data,
count(),
true, nOffset,
new Tuple<int, T>(nIdxR, fR),
new Tuple<int, T>(nIdxG, fG),
new Tuple<int, T>(nIdxB, fB));
3089 return new Tuple<T, T, T>(rg[0], rg[1], rg[2]);
3093 m_cuda.
SetPixel(
mutable_gpu_data,
count(),
true, nOffset,
new Tuple<int, T>(nIdxR, fR),
new Tuple<int, T>(nIdxG, fG),
new Tuple<int, T>(nIdxB, fB));
3105 public void SaveToImage(
string strFile,
bool bNonZeroExistOnly =
true,
bool bSaveDiff =
false, Dictionary<float, Color> rgSpecialValues =
null)
3124 if (!bNonZeroExistOnly)
3126 Tuple<double, double, double, double> minmax =
minmax_diff(blobWork);
3127 dfMin = minmax.Item1;
3128 dfMax = minmax.Item2;
3135 if (!bNonZeroExistOnly)
3137 Tuple<double, double, double, double> minmax =
minmax_data(blobWork);
3138 dfMin = minmax.Item1;
3139 dfMax = minmax.Item2;
3143 if (nWid == 1 && nHt == 1)
3158 Bitmap bmp =
new Bitmap(nNumX * nWid + (nNumX - 1), nNumY * nHt + (nNumY - 1));
3159 using (Graphics g = Graphics.FromImage(bmp))
3161 g.FillRectangle(Brushes.Black, 0, 0, bmp.Width, bmp.Height);
3172 for (
int y = 0; y < nNumY; y++)
3174 for (
int x = 0; x < nNumX; x++)
3176 for (
int h = 0; h < nHt; h++)
3178 for (
int w = 0; w < nWid; w++)
3180 int nIdx = y * nNumX * nHt * nWid + x * nHt * nWid + h * nWid + w;
3181 float fVal = rgData[nIdx];
3182 Color clr = Color.Empty;
3184 if (rgSpecialValues !=
null && rgSpecialValues.ContainsKey(fVal))
3186 clr = rgSpecialValues[fVal];
3190 if (bNonZeroExistOnly)
3196 int nClr = (int)(255 * (rgData[nIdx] - dfMin) / (0 - dfMin));
3197 clr = Color.FromArgb(nClr, 0, 0);
3202 if (bNonZeroExistOnly)
3208 int nClr = (int)(255 * (rgData[nIdx] - 0) / (dfMax - 0));
3209 clr = Color.FromArgb(0, nClr, 0);
3247 private void drawImage(
Blob<T> b,
string strFile)
3261 using (FileStream fs = File.Open(strFile, FileMode.Create))
3262 using (BinaryWriter bw =
new BinaryWriter(fs))
3264 bw.Write((
byte)0x93);
3265 bw.Write((
byte)0x4E);
3266 bw.Write((
byte)0x55);
3267 bw.Write((
byte)0x4D);
3268 bw.Write((
byte)0x50);
3269 bw.Write((
byte)0x59);
3270 bw.Write((
byte)0x01);
3271 bw.Write((
byte)0x00);
3273 string strHeader =
"{'descr': '<f4', 'fortran_order': False, 'shape': (";
3274 for (
int i = 0; i <
shape().Count; i++)
3276 strHeader +=
shape(i).ToString() +
",";
3279 strHeader = strHeader.TrimEnd(
',');
3282 strHeader = strHeader.PadRight(117,
' ');
3285 byte bLen = (byte)strHeader.Length;
3287 bw.Write((
byte)0x00);
3289 foreach (
char ch
in strHeader)
3300 for (
int i = 0; i < rgData.Length; i++)
3302 bw.Write(rgData[i]);
3316 public static void SaveToNumpy(
string strFile,
float[] rgData,
int[] rgShape)
3318 using (FileStream fs = File.Open(strFile, FileMode.Create))
3319 using (BinaryWriter bw =
new BinaryWriter(fs))
3321 bw.Write((
byte)0x93);
3322 bw.Write((
byte)0x4E);
3323 bw.Write((
byte)0x55);
3324 bw.Write((
byte)0x4D);
3325 bw.Write((
byte)0x50);
3326 bw.Write((
byte)0x59);
3327 bw.Write((
byte)0x01);
3328 bw.Write((
byte)0x00);
3330 string strHeader =
"{'descr': '<f4', 'fortran_order': False, 'shape': (";
3331 for (
int i = 0; i < rgShape.Length; i++)
3333 strHeader += rgShape[i].ToString() +
",";
3336 strHeader = strHeader.TrimEnd(
',');
3339 strHeader = strHeader.PadRight(117,
' ');
3342 byte bLen = (byte)strHeader.Length;
3344 bw.Write((
byte)0x00);
3346 foreach (
char ch
in strHeader)
3351 for (
int i = 0; i < rgData.Length; i++)
3353 bw.Write(rgData[i]);
3367 public static void SaveToNumpy(
string strFile,
int[] rgData,
int[] rgShape)
3369 using (FileStream fs = File.Open(strFile, FileMode.Create))
3370 using (BinaryWriter bw =
new BinaryWriter(fs))
3372 bw.Write((
byte)0x93);
3373 bw.Write((
byte)0x4E);
3374 bw.Write((
byte)0x55);
3375 bw.Write((
byte)0x4D);
3376 bw.Write((
byte)0x50);
3377 bw.Write((
byte)0x59);
3378 bw.Write((
byte)0x01);
3379 bw.Write((
byte)0x00);
3381 string strHeader =
"{'descr': '<i4', 'fortran_order': False, 'shape': (";
3382 for (
int i = 0; i < rgShape.Length; i++)
3384 strHeader += rgShape[i].ToString() +
",";
3387 strHeader = strHeader.TrimEnd(
',');
3390 strHeader = strHeader.PadRight(117,
' ');
3393 byte bLen = (byte)strHeader.Length;
3395 bw.Write((
byte)0x00);
3397 foreach (
char ch
in strHeader)
3402 for (
int i = 0; i < rgData.Length; i++)
3404 bw.Write(rgData[i]);
3418 public static void SaveToNumpy(
string strFile,
long[] rgData,
int[] rgShape)
3420 using (FileStream fs = File.Open(strFile, FileMode.Create))
3421 using (BinaryWriter bw =
new BinaryWriter(fs))
3423 bw.Write((
byte)0x93);
3424 bw.Write((
byte)0x4E);
3425 bw.Write((
byte)0x55);
3426 bw.Write((
byte)0x4D);
3427 bw.Write((
byte)0x50);
3428 bw.Write((
byte)0x59);
3429 bw.Write((
byte)0x01);
3430 bw.Write((
byte)0x00);
3432 string strHeader =
"{'descr': '<i8', 'fortran_order': False, 'shape': (";
3433 for (
int i = 0; i < rgShape.Length; i++)
3435 strHeader += rgShape[i].ToString() +
",";
3438 strHeader = strHeader.TrimEnd(
',');
3441 strHeader = strHeader.PadRight(117,
' ');
3444 byte bLen = (byte)strHeader.Length;
3446 bw.Write((
byte)0x00);
3448 foreach (
char ch
in strHeader)
3453 for (
int i = 0; i < rgData.Length; i++)
3455 bw.Write(rgData[i]);
3473 public Tuple<float[], int[]>
LoadFromNumpy(
string strFile,
bool bLoadDiff =
false,
bool bLoadDataOnly =
false,
Log log =
null,
int nMax =
int.MaxValue)
3475 using (FileStream fs = File.OpenRead(strFile))
3476 using (BinaryReader br =
new BinaryReader(fs))
3478 byte[] rgMagic =
new byte[6];
3479 for (
int i = 0; i < rgMagic.Length; i++)
3481 rgMagic[i] = br.ReadByte();
3484 if (rgMagic[0] != 0x93 || rgMagic[1] != 0x4E || rgMagic[2] != 0x55 || rgMagic[3] != 0x4D || rgMagic[4] != 0x50 || rgMagic[5] != 0x59)
3485 throw new Exception(
"The file is not a valid Numpy file!");
3487 byte bMajor = br.ReadByte();
3488 byte bMinor = br.ReadByte();
3490 if (bMajor != 1 || bMinor != 0)
3491 throw new Exception(
"The file is not a valid Numpy file!");
3493 byte bHeaderLen1 = br.ReadByte();
3494 byte bHeaderLen2 = br.ReadByte();
3495 int nHeaderLen = bHeaderLen2 << 8 | bHeaderLen1;
3497 byte[] rgHeader =
new byte[nHeaderLen];
3498 for (
int i = 0; i < rgHeader.Length; i++)
3500 rgHeader[i] = br.ReadByte();
3502 string strHeader = Encoding.ASCII.GetString(rgHeader);
3507 int nCount = parseHeader(strHeader, out bFortranOrder, out rgShape, out dataType, nMax);
3509 throw new Exception(
"The file size is too large for a flat array.");
3512 throw new Exception(
"Currently the fortran ordering is not supported");
3514 Stopwatch sw =
null;
3517 sw =
new Stopwatch();
3521 float[] rgData =
new float[nCount];
3522 for (
int i = 0; i < rgData.Length; i++)
3524 if (dataType == typeof(
float))
3525 rgData[i] = br.ReadSingle();
3526 else if (dataType == typeof(
double))
3527 rgData[i] = (float)br.ReadDouble();
3528 else if (dataType == typeof(
int))
3529 rgData[i] = (
float)br.ReadInt32();
3530 else if (dataType == typeof(
long))
3531 rgData[i] = (
float)br.ReadInt64();
3532 else if (dataType == typeof(
bool))
3533 rgData[i] = (br.ReadBoolean()) ? 1 : 0;
3535 throw new Exception(
"Unsupported data type!");
3539 if (sw.Elapsed.TotalMilliseconds > 1000)
3541 double dfPct = (double)i / (
double)rgData.Length;
3542 string strOut =
"Loading '" + strFile +
"' at " + dfPct.ToString(
"P5") +
"...";
3543 log.WriteLine(strOut,
true);
3559 return new Tuple<float[], int[]>(rgData, rgShape);
3578 public static Tuple<List<float[]>,
int[], List<string>>
LoadFromNumpy(
string strFile,
Log log =
null,
int nMax =
int.MaxValue,
int nStartIdx = 0,
int nCount =
int.MaxValue)
3580 using (FileStream fs = File.OpenRead(strFile))
3581 using (BinaryReader br =
new BinaryReader(fs))
3583 byte[] rgMagic =
new byte[6];
3584 for (
int i = 0; i < rgMagic.Length; i++)
3586 rgMagic[i] = br.ReadByte();
3589 if (rgMagic[0] != 0x93 || rgMagic[1] != 0x4E || rgMagic[2] != 0x55 || rgMagic[3] != 0x4D || rgMagic[4] != 0x50 || rgMagic[5] != 0x59)
3590 throw new Exception(
"The file is not a valid Numpy file!");
3592 byte bMajor = br.ReadByte();
3593 byte bMinor = br.ReadByte();
3595 if (bMajor != 1 || bMinor != 0)
3596 throw new Exception(
"The file is not a valid Numpy file!");
3598 byte bHeaderLen1 = br.ReadByte();
3599 byte bHeaderLen2 = br.ReadByte();
3600 int nHeaderLen = bHeaderLen2 << 8 | bHeaderLen1;
3602 byte[] rgHeader =
new byte[nHeaderLen];
3603 for (
int i = 0; i < rgHeader.Length; i++)
3605 rgHeader[i] = br.ReadByte();
3607 string strHeader = Encoding.ASCII.GetString(rgHeader);
3613 Tuple<int,int>
count = parseHeaderEx(strHeader, out bFortranOrder, out rgShape, out dataType, out nDataTypeSize, nMax);
3616 throw new Exception(
"Currently the fortran ordering is not supported");
3618 Stopwatch sw =
null;
3621 sw =
new Stopwatch();
3628 if (nCount ==
int.MaxValue)
3630 nCount =
count.Item1;
3634 if (nStartIdx + nCount >
count.Item1)
3636 nCount =
count.Item1 - nStartIdx;
3642 rgShape[0] = nCount;
3648 long nSeekPos = fs.Position;
3652 for (
int i = 1; i < rgShape.Length; i++)
3654 nItems *= rgShape[i];
3659 if (dataType == typeof(
float))
3660 nItemSize =
sizeof(float);
3661 else if (dataType == typeof(
double))
3662 nItemSize =
sizeof(
double);
3663 else if (dataType == typeof(
int))
3664 nItemSize =
sizeof(
int);
3665 else if (dataType == typeof(
string))
3668 throw new Exception(
"String data types do not support starting at an index > 0!");
3670 else if (dataType == typeof(
long))
3671 nItemSize =
sizeof(long);
3672 else if (dataType == typeof(
bool))
3673 nItemSize =
sizeof(
bool);
3675 throw new Exception(
"Unsupported data type!");
3677 nSeekPos += nItemSize * nItems * nStartIdx;
3679 fs.Seek(nSeekPos, SeekOrigin.Begin);
3683 ulong ulTotal = (ulong)nCount * (ulong)
count.Item2;
3684 List<float[]> rgData =
new List<float[]>(nCount);
3685 List<string> rgStrData =
new List<string>(nCount);
3688 for (
int i = nStartIdx; i < nStartIdx + nCount && i <
count.Item1; i++)
3690 float[] rgItem =
new float[
count.Item2];
3691 for (
int j = 0; j <
count.Item2; j++)
3693 if (dataType == typeof(
float))
3694 rgItem[j] = br.ReadSingle();
3695 else if (dataType == typeof(
double))
3696 rgItem[j] = (float)br.ReadDouble();
3697 else if (dataType == typeof(
int))
3698 rgItem[j] = (
float)br.ReadInt32();
3699 else if (dataType == typeof(
string))
3701 List<byte> bytes =
new List<byte>();
3702 byte addByte = 0x00;
3703 for (
int c = 0; c < nDataTypeSize * 4; c++)
3705 addByte = br.ReadByte();
3706 if (addByte != 0x00)
3709 strVal = Encoding.UTF8.GetString(bytes.ToArray());
3710 rgStrData.Add(strVal);
3712 else if (dataType == typeof(
long))
3713 rgItem[j] = (float)br.ReadInt64();
3714 else if (dataType == typeof(
bool))
3715 rgItem[j] = (br.ReadBoolean()) ? 1 : 0;
3717 throw new Exception(
"Unsupported data type!");
3721 if (sw.Elapsed.TotalMilliseconds > 1000)
3723 double dfPct = (double)ulIdx / (
double)ulTotal;
3724 string strOut =
"Loading '" + strFile +
"' at " + dfPct.ToString(
"P5") +
"...";
3725 log.WriteLine(strOut,
true);
3736 return new Tuple<List<float[]>,
int[], List<string>>(rgData, rgShape, rgStrData);
3740 private int parseHeader(
string str, out
bool bFortranOrder, out
int[] rgShape, out Type dataType,
int nMax =
int.MaxValue)
3743 List<int> rgShape1 =
new List<int>();
3744 str = str.Trim(
'{',
'}',
' ',
'\n',
',');
3746 dataType = typeof(
object);
3748 string strShape =
null;
3749 string strTarget =
"'shape':";
3750 int nPos = str.IndexOf(strTarget);
3753 strShape = str.Substring(nPos + strTarget.Length);
3754 str = str.Substring(0, nPos);
3756 nPos = strShape.IndexOf(
')');
3757 str += strShape.Substring(nPos + 1);
3758 str = str.Trim(
',',
' ');
3760 strShape = strShape.Substring(0, nPos);
3761 strShape = strShape.Trim(
' ',
'(',
')');
3762 string[] rgShapeStr = strShape.Split(
',');
3764 for (
int i=0; i<rgShapeStr.Length; i++)
3766 string strShape1 = rgShapeStr[i];
3767 if (!
string.IsNullOrEmpty(strShape1))
3769 int nShape =
int.Parse(strShape1);
3771 if (i == 0 && nShape > nMax)
3774 rgShape1.Add(nShape);
3775 nCount *= rgShape1[rgShape1.Count - 1];
3780 rgShape = rgShape1.ToArray();
3781 bFortranOrder =
false;
3783 string[] rgstr = str.Split(
',');
3784 foreach (
string str1
in rgstr)
3786 string[] rgstrKeyVal = str1.Split(
':');
3787 if (rgstrKeyVal.Length != 2)
3788 throw new Exception(
"Invalid header key value, '" + str1 +
"'!");
3790 string strKey = rgstrKeyVal[0].Trim(
'\'',
' ');
3791 string strVal = rgstrKeyVal[1].Trim(
'\'',
' ');
3796 if (strVal ==
"<f4")
3797 dataType = typeof(
float);
3798 else if (strVal ==
"<f8")
3799 dataType = typeof(
double);
3800 else if (strVal ==
"<i4")
3801 dataType = typeof(
int);
3802 else if (strVal ==
"<i8")
3803 dataType = typeof(
long);
3804 else if (strVal ==
"|b1")
3805 dataType = typeof(
bool);
3807 throw new Exception(
"Unsupported data type '" + strVal +
"', currenly only support '<f4'");
3810 case "fortran_order":
3811 bFortranOrder =
bool.Parse(strVal);
3819 private static Tuple<int, int> parseHeaderEx(
string str, out
bool bFortranOrder, out
int[] rgShape, out Type dataType, out
int nDataTypeSize,
int nMax =
int.MaxValue)
3823 List<int> rgShape1 =
new List<int>();
3824 str = str.Trim(
'{',
'}',
' ',
'\n',
',');
3826 dataType = typeof(
object);
3829 string strShape =
null;
3830 string strTarget =
"'shape':";
3831 int nPos = str.IndexOf(strTarget);
3834 strShape = str.Substring(nPos + strTarget.Length);
3835 str = str.Substring(0, nPos);
3837 nPos = strShape.IndexOf(
')');
3838 str += strShape.Substring(nPos + 1);
3839 str = str.Trim(
',',
' ');
3841 strShape = strShape.Substring(0, nPos);
3842 strShape = strShape.Trim(
' ',
'(',
')');
3843 string[] rgShapeStr = strShape.Split(
',');
3845 for (
int i=0; i<rgShapeStr.Count(); i++)
3847 string strShape1 = rgShapeStr[i];
3848 if (!
string.IsNullOrEmpty(strShape1))
3850 int nShape =
int.Parse(strShape1);
3852 if (i == 0 && nShape > nMax)
3855 rgShape1.Add(nShape);
3858 nNum = rgShape1[rgShape1.Count - 1];
3860 nCount *= rgShape1[rgShape1.Count - 1];
3865 rgShape = rgShape1.ToArray();
3866 bFortranOrder =
false;
3868 string[] rgstr = str.Split(
',');
3869 foreach (
string str1
in rgstr)
3871 string[] rgstrKeyVal = str1.Split(
':');
3872 if (rgstrKeyVal.Length != 2)
3873 throw new Exception(
"Invalid header key value, '" + str1 +
"'!");
3875 string strKey = rgstrKeyVal[0].Trim(
'\'',
' ');
3876 string strVal = rgstrKeyVal[1].Trim(
'\'',
' ');
3881 if (strVal ==
"<f4")
3882 dataType = typeof(
float);
3883 else if (strVal ==
"<f8")
3884 dataType = typeof(
double);
3885 else if (strVal ==
"<i4")
3886 dataType = typeof(
int);
3887 else if (strVal ==
"<i8")
3888 dataType = typeof(
long);
3889 else if (strVal ==
"|b1")
3890 dataType = typeof(
bool);
3891 else if (strVal.StartsWith(
"<U"))
3893 strVal = strVal.Substring(2);
3894 nDataTypeSize =
int.Parse(strVal);
3895 dataType = typeof(
string);
3898 throw new Exception(
"Unsupported data type '" + strVal +
"', currenly only support '<f4'");
3901 case "fortran_order":
3902 bFortranOrder =
bool.Parse(strVal);
3907 return new Tuple<int, int>(nNum, nCount);
3922 public void MatMul(
Blob<T> blobA,
Blob<T> blobB,
bool bReshape =
false,
bool bTransA =
false,
bool bTransB =
false,
double dfScale = 1.0,
bool bADiff =
false,
bool bBDiff =
false,
bool bCDiff =
false)
3928 m_log.
FAIL(
"Blob A does not have a diff value!");
3930 m_log.
FAIL(
"Blob B does not have a diff value!");
3932 for (
int i = 0; i < blobA.
num_axes - 2; i++)
3934 m_log.
CHECK_EQ(blobA.
shape(i), blobB.
shape(i),
"Blob A and B must have the same shape at axis '" + i.ToString() +
"'!");
3938 m_log.
FAIL(
"This blob does not have a diff value!");
3941 uint nOuterCount = (uint)blobA.
count(0, nAxis);
3942 int m = blobA.
shape(2);
3943 int n = blobB.
shape(3);
3944 int k = blobA.
shape(3);
3948 rgShape[rgShape.Count - 1] = n;
3949 rgShape[rgShape.Count - 2] = m;
3954 m_log.
CHECK(
CompareShape(rgShape),
"This (resulting) blob does not have the correct shape! Expected shape = " +
Utility.ToString<
int>(rgShape));
3960 m_cuda.
matmul(nOuterCount, m, n, k, hA, hB, hC, dfScale, bTransA, bTransB);
3979 blobA.
MatMul(
this, blobWork,
false,
false,
false, 1,
true,
false,
true);
3981 blobB.
MatMul(blobWork,
this,
false,
false,
false, 1,
false,
true,
true);
The Datum class is a simple wrapper to the SimpleDatum class to ensure compatibility with the origina...
The ImageData class is a helper class used to convert between Datum, other raw data,...
static Datum GetImageData(Bitmap bmp, SimpleDatum sd, bool? bIsDataRealOverride=null, int[] rgFocusMap=null)
The GetImageData function converts a Bitmap into a Datum.
static Bitmap GetImage(SimpleDatum d, ColorMapper clrMap=null, List< int > rgClrOrder=null)
Converts a SimplDatum (or Datum) into an image, optionally using a ColorMapper.
The LockBitmap class provides very efficient SetPixel and GetPixel functionality of a bitmap by using...
void SetPixel(int x, int y, Color color)
Set the color of the specified pixel
void UnlockBits()
Unlock bitmap data, releasing its underlying data.
void LockBits()
Lock bitmap data to access its underlying raw data.
The Log class provides general output in text form.
void CHECK(bool b, string str)
Test a flag for true.
void WriteLine(string str, bool bOverrideEnabled=false, bool bHeader=false, bool bError=false, bool bDisable=false)
Write a line of output.
void FAIL(string str)
Causes a failure which throws an exception with the desciptive text.
void CHECK_EQ(double df1, double df2, string str)
Test whether one number is equal to another.
void CHECK_LE(double df1, double df2, string str)
Test whether one number is less than or equal to another.
void CHECK_GE(double df1, double df2, string str)
Test whether one number is greater than or equal to another.
void CHECK_LT(double df1, double df2, string str)
Test whether one number is less than another.
The SimpleDatum class holds a data input within host memory.
int Channels
Return the number of channels of the data.
int Width
Return the width of the data.
int Index
Returns the index of the SimpleDatum.
int Height
Return the height of the data.
The Utility class provides general utility funtions.
static int CanonicalAxisIndex(int nIdx, int nNumAxes)
Returns the 'canonical' version of a (usually) user-specified axis, allowing for negative indexing (e...
static int Count(List< int > rgShape, int nStartIdx=0, int nEndIdx=-1)
Return the count of items given the shape.
static double[] ConvertVec(float[] rgf)
Convert an array of float to an array of generics.
The Blob is the main holder of data that moves through the Layers of the Net.
Blob< T > MathDiv(T fScale)
Clones the input Blob and divides a scalar from all of the clones data items.
void Percentile(Blob< T > blobY, double dfPercentile)
Calculates the percentile and places the result in blobY.
int channels
DEPRECIATED; legacy shape accessor channels: use shape(1) instead.
Blob(CudaDnn< T > cuda, Log log, List< int > rgShape, bool bIncludeDiff=true, bool bUseHalfSize=false)
The Blob constructor.
double sum(float[] rgDf=null, bool bDiff=false)
Calculate the sum of the blob data.
void SetData(T[] rgData, int nCount=-1, bool bSetCount=true)
Sets a number of items within the Blob's data.
void ShareData(Blob< T > b)
Set the data to point to the data of the other blob – useful in Layers which simply perform a copy in...
double min_data
Returns the minimum value in the data of the Blob.
double max_data
Returns the maximum value in the data of the Blob.
int LegacyShape(int nIdx)
Returns the legacy shape at a given axis.
void MatMul(Blob< T > blobA, Blob< T > blobB, bool bReshape=false, bool bTransA=false, bool bTransB=false, double dfScale=1.0, bool bADiff=false, bool bBDiff=false, bool bCDiff=false)
MatMul blobA with blobB and place the result in this blob (e.g. this = matmul(A, B))....
int height
DEPRECIATED; legacy shape accessor height: use shape(2) instead.
Blob(CudaDnn< T > cuda, Log log, Blob< T > b, bool bUseHalfSize=false)
The Blob constructor.
int count(int nStartIdx)
Compute the volume of a slice spanning from a particular first axis to the final axis.
void MatMulGrad(Blob< T > blobA, Blob< T > blobB, Blob< T > blobWork, double dfScale=1.0)
Calculates and propagates the gradient for blobA and BlobB given the input gradient in this blob's di...
int count(int nStartIdx, int nEndIdx)
Compute the volume of a slice; i.e., the product of dimensions among a range of axes.
Blob(CudaDnn< T > cuda, Log log, bool bIncludeDiff=true, bool bUseHalfSize=false)
The Blob constructor.
int num_axes
Returns the number of axes in the Blob.
Tuple< double, double, double, double > minmax_data(Blob< T > work, bool bDetectNans=false, bool bUseChunks=false)
Returns the minimum and maximum values in the data of the Blob.
double? GetParameter(string strName)
Get a blob parameter.
long mutable_gpu_diff
Returns the diff GPU handle used by the CudaDnn connection.
void SaveToImage(string strFile, bool bNonZeroExistOnly=true, bool bSaveDiff=false, Dictionary< float, Color > rgSpecialValues=null)
Save the Blob to an image where values less than 0 are colored red, and values greater than 0 are col...
void scale_diff(T fScaleFactor)
Scale the blob diff by a constant factor.
Tuple< T, T, T > SetPixel(int nX, int nY, Tuple< T, T, T > pixel, bool bReturnOriginal=false, TransformationParameter.COLOR_ORDER order=TransformationParameter.COLOR_ORDER.RGB, int nOffset=0)
Sets a pixel to the values within a three item tuple where the first item is assigned RED,...
T[] mutable_cpu_diff
Get diff from the GPU and bring it over to the host, or Set diff from the Host and send it over to th...
T GetDiff(int nIdx)
Returns the diff at a given flat index within the Blob.
bool CompareShape(int[] rgShape, bool bCompareCpuDataLen=false)
Compares the shape of this blob to another shape.
T data_at(int n, int c, int h, int w)
Returns the data at a given location in the Blob.
T sumsq_diff()
Calcualte the sum of squares (L2 norm squared) of the diff.
long mutable_gpu_data
Returns the data GPU handle used by the CudaDnn connection.
void SetDiff(double dfVal, int nStartIdx, int nCount)
Set a diff range with a given value.
void Share(Blob< T > b)
Share another Blob with this one, by setting the data and diff to the same data and diff of the other...
Blob(CudaDnn< T > cuda, Log log, int nNum, int nChannels, int nHeight, int nWidth, bool bIncludeDiff=true, bool bUseHalfSize=false)
DEPRECIATED; use
object Tag
Returns a user defined object associated with the Blob.
void Unsqueeze(int nNumAxes)
Unsqueeze the shape by adding shape=1 on each axis until the 'nNumAxes' is reached.
void CopyFromAndTransposeHeightWidth(Blob< T > blobSrc, bool bCopyDiff=false, bool bUseCuda=true)
Copy from a source Blob and transpose the height and width of the copy.
static Blob< T > Load(CudaDnn< T > cuda, Log log, BinaryReader br, bool bData, bool bDiff)
Lods a new Blob from a binary reader.
int num_true_axes
Returns the number of true axes, ignoring the trailing ones.
bool HalfSize
Returns whether or not this blob is using half sizes.
void Update()
The 'update' method is used for parameter blobs in a Net.
string shape_string
Returns a string describing the Blob's shape.
static Blob< T > FromByteArray(CudaDnn< T > cuda, Log log, byte[] rg)
A new Blob is created from the byte array, previously saved with ToByteArray.
int offset(List< int > rgIdx)
Returns the flat offset given the array of axes values.
void SetCPUData(T[] rg)
Sets just the CPU data to the data specified.
void Reshape(BlobShape shape, bool? bUseHalfSize=null)
Change the dimensions of the blob, allocating new memory if necessary.
void CopyParameters(Blob< T > b)
Copy the parameters from another blob.
T[] mutable_cpu_data
Get data from the GPU and bring it over to the host, or Set data from the Host and send it over to th...
static void SaveToNumpy(string strFile, long[] rgData, int[] rgShape)
Save a blob with data to a Numpy .npy file.
T asum_diff()
Compute the sum of absolute values (L1 norm) of the diff.
static Tuple< List< float[]>, int[], List< string > > LoadFromNumpy(string strFile, Log log=null, int nMax=int.MaxValue, int nStartIdx=0, int nCount=int.MaxValue)
Load the long, int, bool, float, or double data from a very large Numpy array .npy file,...
static T One
Returns One (1) in type T.
Blob< T > Clone()
Copies the Blob, including its data and diff.
void ConvertToBase(long hWorkMem, ulong lWorkSize, bool bData, bool bDiff)
Converts this blob from the half type to the base type.
bool DiffExists
Returns whether or not the Diff portion exists.
SyncedMemory< T > diff
Returns the SyncedMemory that stores the diff.
void ConvertToHalf(long hWorkMem, ulong lWorkSize, bool bData, bool bDiff)
Converts this blob from its base type to the half type.
void Reshape(List< int > rgShape, bool? bUseHalfSize=null)
Change the dimensions of the blob, allocating new memory if necessary.
Blob(CudaDnn< T > cuda, Log log, SimpleDatum d, bool bCopyData=false, bool bIncludeDiff=true, bool bUseHalfSize=false)
The Blob constructor.
int CanonicalAxisIndex(int nIdx)
Returns the 'canonical' version of a (usually) user-specified axis, allowing for negative indexing (e...
Blob(CudaDnn< T > cuda, Log log, int[] rgShape, bool bIncludeDiff=true, bool bUseHalfSize=false)
The Blob constructor.
T[] cpu_data
Returns the last host data retrieved from the GPU.
void SaveToNumpy(string strFile, bool bSaveDiff=false)
Save a blob with data to a Numpy .npy file.
void Reshape(int nNum, int nChannels, int nHeight, int nWidth, bool? bUseHalfSize=null)
DEPRECIATED; use
BLOB_TYPE type
Returns the BLOB_TYPE of the Blob.
double GetMinData(out long lPos)
Returns the minimum data and the position where the minimum is located in the data.
double std(double? dfMean=null, float[] rgDf=null)
Calculate the standard deviation of the blob data.
Blob< T > MathSub(Blob< T > blobA)
Clones the input Blob and subtracts the data from this blob from it.
double GetMaxDiff(out long lPos)
Returns the maximum diff and the position where the maximum is located in the diff.
double min_diff
Returns the minimum value in the diff of the Blob.
Datum ToDatum()
Returns a new Datum that contains the shape and data of the Blob.
Tuple< double, double, double, double > minmax_diff(Blob< T > work, bool bDetectNans=false, bool bUseChunks=false)
Returns the minimum and maximum values in the diff of the Blob.
long CopyFrom(Blob< T > src, bool bCopyDiff=false, bool bReshape=false, long hDstHostBuffer=0, bool bIgnoreShape=false)
Copy from a source Blob.
double mean(float[] rgDf=null, bool bDiff=false)
Calculate the mean of the blob data.
static void SaveToNumpy(string strFile, int[] rgData, int[] rgShape)
Save a blob with data to a Numpy .npy file.
bool CompareShape(List< int > rgShape, bool bCompareCpuDataLen=false)
Compares the shape of this blob to another shape.
void Dispose()
Releases all resources used by the Blob (including both GPU and Host).
bool reshape_when_sharing
When true, this Blob is reshaped to the source when sharing the source data (default = false).
byte[] ToByteArray()
Saves this Blob to a byte array.
int shape(int nIdx)
Returns the dimension of the nIdx'th axis (or the negative nIdx'th axis from teh end,...
Blob< T > MathAdd(Blob< T > blobA, T fScale)
Clones the input Blob, scales the clone and then adds the data from this Blob to it.
bool Compare(Blob< T > other, Blob< T > work, bool bDiff=false, double dfTol=1e-8, bool bZeroCheck=true, bool bFullCompare=false, bool bDetectNans=true, bool bForceOtherData=false)
Compare the data (or diff) of one blob to another and return true if all items fall within the specif...
void CopyFrom(Blob< T > src, int nSrcOffset, int nDstOffset, int nCount, bool bCopyData, bool bCopyDiff)
Copy from a source Blob.
void scale_to_range(double dfMin, double dfMax)
Scale the data in the blob to the range [dfMin,dfMax].
bool ShapeEquals(BlobProto bp)
Compares the shape of this blob to the shape within a BlobProto.
T[] update_cpu_diff()
Update the CPU diff by transferring the GPU diff over to the Host.
void scale_data(double df)
Scale the data by a scaling factor.
int width
DEPRECIATED; legacy shape accessor width: use shape(3) instead.
void FromProto(BlobProto bp, bool bReshape=true)
Create a new Blob from a given BlobProto.
T diff_at(List< int > rgIdx)
Returns the diff at a given location in the Blob.
double GetMinDiff(out long lPos)
Returns the minimum diff and the position where the minimum is located in the diff.
long gpu_shape
Returns the shape GPU handle used by the CudaDnn connection. The shape data contains the shape inform...
void add_scalar(double dfVal)
Adds a scalar value to the Blob.
void SetParameter(string strName, double dfVal)
Set a blob parameter.
Tuple< T, T, T > SetPixel(int nX, int nY, byte R, byte G, byte B, TransformationParameter.COLOR_ORDER order=TransformationParameter.COLOR_ORDER.RGB)
Set the values of a 3 channel image embedded within the blob in the order RGB or BGR where the full h...
BlobProto ToProto(bool bWriteDiff=false)
Writes the Blob to a new BlobProto.
Blob(Blob< T > blob, long lCount, long lOffset)
The Blob constructor used to copy another blob by creating memory pointers to its data thus sharing t...
void Reshape(int[] rgShape, bool? bUseHalfSize=null)
Change the dimensions of the blob, allocating new memory if necessary.
Tuple< float[], int[]> LoadFromNumpy(string strFile, bool bLoadDiff=false, bool bLoadDataOnly=false, Log log=null, int nMax=int.MaxValue)
Load a blob with data from a Numpy array .npy file.
void AsyncGpuPush(long hStream)
Asynchronously pushes the CPU data, previously set with SetCPUData, to the GPU.
ulong GetConversionWorkSize(bool bUseHalfSize)
Returns the amount of memory (in bytes) required to convert from base to half and back.
bool freeze_learning
Specifies whether or not the diff is applied to the data during Update. When freeze learning = true,...
double max_diff
Returns the maximum value in the diff of the Blob.
List< int > shape()
Returns an array where each element contains the shape of an axis of the Blob.
static T Zero
Returns Zero (0) in type T.
T GetData(int nIdx)
Returns the data at a given flat index within the Blob.
SyncedMemory< T > data
Returns the SyncedMemory that stores the data.
T sumsq_data()
Calcualte the sum of squares (L2 norm squared) of the data.
bool CompareEx(Blob< T > other, Blob< T > work, out double dfMin, out double dfMax, bool bDiff=false, double dfTol=1e-8, bool bZeroCheck=true, bool bFullCompare=false, bool bDetectNans=true, bool bForceOtherData=false)
Compare the data (or diff) of one blob to another and return true if all items fall within the specif...
static void SaveToNumpy(string strFile, float[] rgData, int[] rgShape)
Save a blob with data to a Numpy .npy file.
T[] update_cpu_data()
Update the CPU data by transferring the GPU data over to the Host.
override string ToString()
Returns a string representation of the Blob.
void Save(BinaryWriter bw, bool bData, bool bDiff, bool bIncludeName=true)
Saves this Blob to a binary stream.
T asum_data()
Compute the sum of absolute values (L1 norm) of the data.
const int MAX_BLOB_AXES
Defines the maximum number of Axes supported by the Blob.
void NormalizeData(double? dfMean=null, double? dfStd=null)
Normalize the blob data by subtracting the mean and dividing by the standard deviation.
void scale_data(T fScaleFactor)
Scale the blob data by a constant factor.
static Blob< T > LoadBinary(CudaDnn< T > cuda, Log log, string strFile, bool bData, bool bDiff)
Loads a blob from a binary file (previously saved with SaveBinary).
int count()
Returns the total number of items in the Blob.
void ShareDiff(Blob< T > b)
Set the diff to point to the diff of the other blob – useful in Layers which simply perform a copy in...
void SetData(SimpleDatum d, bool bReshape, bool bCopyData=true)
Sets the Blob values to the data contained within a SimpleDatum.
void CopyFromAndPad(Blob< T > src, double dfPad=0, bool bCopyDiff=false)
Copy the source data to this Blob, and if this blob is larger than the source, pad this blob with 'df...
void ReshapeLike(Blob< T > b, bool? bUseHalfSize=null)
Reshape this Blob to have the same shape as another Blob.
bool Compare(CudaDnn< double > cuda, Blob< T > other, Blob< double > work, bool bDiff=false, double dfTol=1e-8)
Compare the data (or diff) of one blob to another and return true if all items fall within the specif...
T diff_at(int n, int c, int h, int w)
Returns the diff at a given location in the Blob.
string Name
Get/set the name of the Blob.
int offset(int n, int c=0, int h=0, int w=0)
Returns the flat offset given the number, channel, height and width.
CudaDnn< T > Cuda
Returns the CudaDnn object that manages the Blob's memory."/>
long gpu_diff
Returns the diff GPU handle used by the CudaDnn connection.
virtual void Dispose(bool bDisposing)
Releases all resources used by the Blob (including both GPU and Host).
T data_at(List< int > rgIdx)
Returns the data at a given location in the Blob.
void SetData(double dfVal, int nStartIdx, int nCount)
Set a data range with a given value.
string ToSizeString()
Returns a string describing the 4D shape of the Blob.
void SaveBinary(string strFile, bool bData, bool bDiff, bool bIncludeName=true)
Saves the blob to a binary file.
string ToString(int nMax, bool bDiff=false)
Get the string representation containing up to the first 'nMax' items.
void SetDiff(T[] rgDiff, int nCount=-1, bool bSetCount=true)
Sets a number of items within the Blob's diff.
Blob(CudaDnn< T > cuda, Log log, BlobProto bp, bool bUseHalfSize=false)
The Blob constructor.
void scale_diff(double df)
Scale the diff by a scaling factor.
bool Padded
Get/set the padding state of the blob.
void SetDiff(double dfVal, int nIdx=-1)
Either sets all of the diff items in the Blob to a given value, or alternatively only sets a single i...
void CopyFrom(Blob< T > blobSrc, int nChannelFrom, int nChannelTo, bool bCopyDiff=false)
Copy all data along a given channel from the source.
int num
DEPRECIATED; legacy shape accessor num: use shape(0) instead.
T[] cpu_diff
Returns the last host diff retrieved from the GPU.
static T MinusOne
Returns MinusOne (-1) in type T.
void SetData(T fVal, int nIdx=-1)
Either sets all of the data items in the Blob to a given value, or alternatively only sets a single i...
bool ValidateData(Blob< T > work, bool bDiff=false)
Validate the data or diff looking for NAN or Inf.
bool snapshot_requested
Get/set the snapshot request.
Blob< T > Resize(List< int > rgShape)
The Resize method resizes the 3rd and 4th axes of the blob.
long gpu_data
Returns the data GPU handle used by the CudaDnn connection.
void SetData(double dfVal, int nIdx=-1)
Either sets all of the data items in the Blob to a given value, or alternatively only sets a single i...
double GetMaxData(out long lPos)
Returns the maximum data and the position where the maximum is located in the data.
The CudaDnn object is the main interface to the Low-Level Cuda C++ DLL.
void matmul(uint nOuterCount, int m, int n, int k, long hA, long hB, long hC, double dfScale=1.0, bool bTransA=false, bool bTransB=false)
Perform matmul operation hC = matmul(hA, hB), where hA, hB and hC are all in row-major format.
void copy(int nCount, long hSrc, long hDst, int nSrcOffset=0, int nDstOffset=0, long hStream=-1, bool? bSrcHalfSizeOverride=null, bool? bDstHalfSizeOverride=null)
Copy data from one block of GPU memory to another.
void mul_scalar(int n, double fAlpha, long hY)
Mutlipy each element of Y by a scalar.
void scal(int n, double fAlpha, long hX, int nXOff=0)
Scales the data in X by a scaling factor.
void max(int n, long hA, long hB, long hY)
Calculates the max of A and B and places the result in Y. This max is only computed on a per item bas...
void FreeMemory(long hMem)
Free previously allocated GPU memory.
void add_scalar(int n, double fAlpha, long hY)
Adds a scalar value to each element of Y.
void scale_to_range(int n, long hX, long hY, double fMin, double fMax)
Scales the values in X and places the result in Y (can also run inline where X = Y).
long AllocMemory(List< double > rg)
Allocate a block of GPU memory and copy a list of doubles to it.
void sub(int n, long hA, long hB, long hY, int nAOff=0, int nBOff=0, int nYOff=0, int nB=0)
Subtracts B from A and places the result in Y.
T[] SetPixel(long hMem, int nCount, bool bReturnOriginal, int nOffset, params Tuple< int, T >[] rgPixel)
Set a pixel value where each pixel is defined a set index, value tuple.
void add(int n, long hA, long hB, long hC, long hY)
Adds A, B and C and places the result in Y.
static ulong basetype_size(bool bUseHalfSize)
Returns the base type size in bytes.
void axpy(int n, double fAlpha, long hX, long hY)
Multiply the vector X by a scalar and add the result to the vector Y.
void transposeHW(int n, int c, int h, int w, long hSrc, long hDst)
Transpose a n*c number of matrices along the height and width dimensions. All matrices are in row-maj...
Tuple< double, double, double, double > minmax(int n, long hA, long hWork1, long hWork2, bool bDetectNans=false, int nAOff=0)
Finds the minimum and maximum values within A.
double[] GetMemoryDouble(long hMem, long lCount=-1)
Retrieves the GPU memory as an array of doubles.
void channel_percentile(int nCount, int nOuterNum, int nChannels, int nInnerNum, long hX, long hY, double dfPercentile)
Calculates the percentile along axis = 0.
void set(int nCount, long hHandle, double fVal, int nIdx=-1)
Set the values of GPU memory to a specified value of type
double asum_double(int n, long hX, int nXOff=0)
Computes the sum of absolute values in X.
T asum(int n, long hX, int nXOff=0)
Computes the sum of absolute values in X.
void min(int n, long hA, long hB, long hY)
Calculates the min of A and B and places the result in Y. This min is only computed on a per item bas...
T[] get(int nCount, long hHandle, int nIdx=-1)
Queries the GPU memory by copying it into an array of type 'T'.
float[] GetMemoryFloat(long hMem, long lCount=-1)
Retrieves the GPU memory as an array of float.
T dot(int n, long hX, long hY, int nXOff=0, int nYOff=0)
Computes the dot product of X and Y.
The SyncedMemory manages the low-level connection between the GPU and host memory.
bool HalfSize
Returns whether or not the sync memory is half-sized memory.
void async_gpu_push(long hStream, T[] rg)
Pushes the host data, previously set with set_cpu_data_locally(), to the GPU.
long gpu_data
Returns the handle to the GPU memory.
object Tag
Get/set data associated with the synced memory.
void set_gpu_data(long hData, long lCount, long lOffset)
Copies a new Memory Pointer within the low-level CudaDnnDLL where a Memory Pointer uses another alrea...
T[] mutable_cpu_data
Get/set the mutable host data.
long Copy(SyncedMemory< T > src, long hDstHostBuffer=0)
Copy another SyncedMemory into this one.
void Dispose()
Releases all GPU and host resources used.
void SetData(T[] rgData, int nCount, bool bSetCount=true)
Sets the array of host data on the GPU and re-allocates the GPU memory if needed.
void Allocate(long lCount, bool bUseHalfSize=false)
Allocate a number of items in GPU memory and save the handle.
long Capacity
Returns the total amount of GPU memory held by this SyncedMemory.
T GetAt(int nIdx)
Return a value at a given index.
long mutable_gpu_data
Returns the mutable handle to GPU data.
T[] update_cpu_data(long lCount=-1)
Updates the host data by copying the GPU data to the host data.
T[] cpu_data
Returns the data on the CPU that has already been transferred from GPU to CPU.
void ZeroAll()
Set all items in the GPU memory up to the Capacity, to zero.
void set_cpu_data_locally(T[] rg)
This does not place the data on the GPU - call async_gpu_push() to move it to the GPU.
long Count
Returns the current count of items in this SyncedMemory. Note, the Count may be less than the Capacit...
The BlobProto contains the descripion of a blob.
List< float > data
Get/set the data as a List of float.
List< double > double_diff
Get/set the diff as a List of double.
BlobShape shape
Specifies the shape of the Blob.
List< double > double_data
Get/set the data as a List of double.
int? num
Specifies the number of inputs (such as images) in the Blob.
List< float > diff
Get/set the diff as a List of float.
int? height
Specifies the height of each input.
int? channels
Specifies the number of images per input.
int? width
Specifies the width of each input.
Specifies the shape of a Blob.
List< int > dim
The blob shape dimensions.
The MyCaffe.basecode contains all generic types used throughout MyCaffe.
The MyCaffe.common namespace contains common MyCaffe classes.
BLOB_TYPE
Defines the tpe of data held by a given Blob.
The MyCaffe.param namespace contains parameters used to create models.
The MyCaffe namespace contains the main body of MyCaffe code that closesly tracks the C++ Caffe open-...