@@ -56,6 +56,29 @@ generic<class ElemType>
56
56
m_colIndices = gcnew array<int >(size);
57
57
m_size = size;
58
58
}
59
+
60
+ property int Size
61
+ {
62
+ int get () { return m_size; }
63
+ }
64
+
65
+ property array<ElemType>^ Buffer
66
+ {
67
+ array<ElemType>^ get () { return m_buffer; }
68
+ }
69
+
70
+ property array<int >^ Indices
71
+ {
72
+ array<int >^ get () { return m_indices; }
73
+ }
74
+
75
+ property array<int >^ ColIndices
76
+ {
77
+ array<int >^ get () { return m_colIndices;
78
+ }
79
+ }
80
+
81
+ private:
59
82
60
83
int m_size;
61
84
@@ -111,15 +134,15 @@ public ref struct VariableLayout
111
134
};
112
135
113
136
// Name of the input
114
- String^ m_name ;
137
+ property String^ Name ;
115
138
116
- DataType m_dataType ;
139
+ property DataType DataKind ;
117
140
118
- StorageType m_storageType ;
141
+ property StorageType StorageKind ;
119
142
120
143
// Dimension of the tensor, flattened to 1 dimension, for one entry on the dynamic axis.
121
144
// E.g. for a tensor [2,3,*] this would be 6.
122
- int m_numElements ;
145
+ property int NumElements ;
123
146
};
124
147
125
148
public ref class VariableSchema : List<VariableLayout^>
@@ -136,7 +159,7 @@ public ref class VariableSchema : List<VariableLayout^>
136
159
List<ValueBuffer<ElemType>^>^ buffers = gcnew List<ValueBuffer<ElemType>^>(this ->Count );
137
160
for (int i = 0 ; i < this ->Count ; i++)
138
161
{
139
- buffers->Add (gcnew ValueBuffer<ElemType>(this [i]->m_numElements * maxLengths[i]));
162
+ buffers->Add (gcnew ValueBuffer<ElemType>(this [i]->NumElements * maxLengths[i]));
140
163
}
141
164
142
165
return buffers;
@@ -149,7 +172,7 @@ public ref class VariableSchema : List<VariableLayout^>
149
172
List<ValueBuffer<ElemType>^>^ buffers = gcnew List<ValueBuffer<ElemType>^>(this ->Count );
150
173
for (int i = 0 ; i < this ->Count ; i++)
151
174
{
152
- buffers->Add (gcnew ValueBuffer<ElemType>(this [i]->m_numElements ));
175
+ buffers->Add (gcnew ValueBuffer<ElemType>(this [i]->NumElements ));
153
176
}
154
177
155
178
return buffers;
@@ -158,14 +181,14 @@ public ref class VariableSchema : List<VariableLayout^>
158
181
159
182
// / Managed wrapper for the native evaluation model
160
183
template <typename ElemType>
161
- public ref class IEvaluateModelExtendedManaged : IDisposable
184
+ public ref class ModelEvaluationExtended : IDisposable
162
185
{
163
186
typedef std::pair<std::wstring, std::vector<ElemType>*> MapEntry;
164
187
165
188
public:
166
- // / <summary>Initializes a new instance of the <see cref="IEvaluateModelExtendedManaged "> class.</summary>
189
+ // / <summary>Initializes a new instance of the <see cref="ModelEvaluationExtended "> class.</summary>
167
190
// / <param name="funcName">Factory function name for retrieving the native model from the dll.</param>
168
- IEvaluateModelExtendedManaged (String^ funcName)
191
+ ModelEvaluationExtended (String^ funcName)
169
192
{
170
193
pin_ptr<const WCHAR> dllname = PtrToStringChars (" evaldll.dll" );
171
194
auto hModule = LoadLibrary (dllname);
@@ -228,9 +251,10 @@ public ref class IEvaluateModelExtendedManaged : IDisposable
228
251
for (auto & lay : outputLayout)
229
252
{
230
253
VariableLayout^ layout = gcnew VariableLayout ();
231
- layout->m_name = gcnew String (lay.m_name .c_str ());
232
- layout->m_dataType = GetDataType (lay.m_dataType );
233
- layout->m_numElements = lay.m_numElements ;
254
+ layout->Name = gcnew String (lay.m_name .c_str ());
255
+ layout->DataKind = GetDataKind (lay.m_dataType );
256
+ layout->NumElements = lay.m_numElements ;
257
+ layout->StorageKind = GetStorageKind (lay.m_storageType );
234
258
235
259
outputSchema->Add (layout);
236
260
}
@@ -275,9 +299,10 @@ public ref class IEvaluateModelExtendedManaged : IDisposable
275
299
for (auto & lay : inputLayout)
276
300
{
277
301
VariableLayout^ layout = gcnew VariableLayout ();
278
- layout->m_name = gcnew String (lay.m_name .c_str ());
279
- layout->m_dataType = GetDataType (lay.m_dataType );
280
- layout->m_numElements = lay.m_numElements ;
302
+ layout->Name = gcnew String (lay.m_name .c_str ());
303
+ layout->DataKind = GetDataKind (lay.m_dataType );
304
+ layout->NumElements = lay.m_numElements ;
305
+ layout->StorageKind = GetStorageKind (lay.m_storageType );
281
306
282
307
inputSchema->Add (layout);
283
308
}
@@ -307,26 +332,54 @@ public ref class IEvaluateModelExtendedManaged : IDisposable
307
332
Native::ValueRefs<ElemType> stdOutputs;
308
333
Native::ValueBuffer<ElemType, Native::VectorRef>* vb = new Native::ValueBuffer<ElemType, Native::VectorRef>();
309
334
335
+ // Hold gc objects in the stack, while performing native actions
336
+ vector<gcroot<array<ElemType>^>*> pinBuffers;
337
+ vector<gcroot<array<int >^>*> pinIndices;
338
+
310
339
// Map the managed space into the native space, results will be written directly into the managed memory space
340
+ // https://msdn.microsoft.com/en-us/library/1dz8byfh.aspx
341
+
311
342
for each (auto item in inputs)
312
343
{
313
- pin_ptr<ElemType> pb = &(item->m_buffer [0 ]);
314
- pin_ptr<int > pi = &(item->m_indices [0 ]);
315
- pin_ptr<int > pci = &(item->m_colIndices [0 ]);
316
- vb->m_buffer .InitFrom (pb, item->m_size , item->m_size );
317
- vb->m_indices .InitFrom (pi , item->m_size , item->m_size );
318
- vb->m_colIndices .InitFrom (pci, item->m_size , item->m_size );
344
+ int size = item->Size ;
345
+ // gcroot object manages the pointer so that it always corresponds to the correct managed location (even after gc relocation)
346
+ gcroot<array<ElemType>^>* pBuf = new gcroot<array<ElemType>^>(item->Buffer );
347
+ gcroot<array<int >^>* pInd = new gcroot<array<int >^>(item->Indices );
348
+ gcroot<array<int >^>* pColInd = new gcroot<array<int >^>(item->ColIndices );
349
+
350
+ pinBuffers.push_back (pBuf);
351
+ pinIndices.push_back (pInd);
352
+ pinIndices.push_back (pColInd);
353
+
354
+ pin_ptr<ElemType> pp = &(*pBuf)[0 ];
355
+ pin_ptr<int > pi = &(*pInd)[0 ];
356
+ pin_ptr<int > pci = &(*pColInd)[0 ];
357
+
358
+ vb->m_buffer .InitFrom (pp, size, size);
359
+ vb->m_indices .InitFrom (pi , size, size);
360
+ vb->m_colIndices .InitFrom (pci, size, size);
361
+
319
362
stdInputs.push_back (*vb);
320
363
}
321
364
322
365
for each (auto item in outputs)
323
366
{
324
- pin_ptr<ElemType> pb = &(item->m_buffer [0 ]);
325
- pin_ptr<int > pi = &(item->m_indices [0 ]);
326
- pin_ptr<int > pci = &(item->m_colIndices [0 ]);
327
- vb->m_buffer .InitFrom (pb, item->m_size , item->m_size );
328
- vb->m_indices .InitFrom (pi , item->m_size , item->m_size );
329
- vb->m_colIndices .InitFrom (pci, item->m_size , item->m_size );
367
+ int size = item->Size ;
368
+ gcroot<array<ElemType>^>* pBuf = new gcroot<array<ElemType>^>(item->Buffer );
369
+ gcroot<array<int >^>* pInd = new gcroot<array<int >^>(item->Indices );
370
+ gcroot<array<int >^>* pColInd = new gcroot<array<int >^>(item->ColIndices );
371
+
372
+ pin_ptr<ElemType> pp = &(*pBuf)[0 ];
373
+ pin_ptr<int > pi = &(*pInd)[0 ];
374
+ pin_ptr<int > pci = &(*pColInd)[0 ];
375
+
376
+ pinBuffers.push_back (pBuf);
377
+ pinIndices.push_back (pInd);
378
+ pinIndices.push_back (pColInd);
379
+ vb->m_buffer .InitFrom (pp, size, size);
380
+ vb->m_indices .InitFrom (pi , size, size);
381
+ vb->m_colIndices .InitFrom (pci, size, size);
382
+
330
383
stdOutputs.push_back (*vb);
331
384
}
332
385
@@ -345,18 +398,18 @@ public ref class IEvaluateModelExtendedManaged : IDisposable
345
398
}
346
399
}
347
400
348
- ~IEvaluateModelExtendedManaged ()
401
+ ~ModelEvaluationExtended ()
349
402
{
350
403
if (m_eval == nullptr )
351
404
{
352
405
return ;
353
406
}
354
407
355
- this ->!IEvaluateModelExtendedManaged ();
408
+ this ->!ModelEvaluationExtended ();
356
409
}
357
410
358
411
protected:
359
- !IEvaluateModelExtendedManaged ()
412
+ !ModelEvaluationExtended ()
360
413
{
361
414
if (m_eval != nullptr )
362
415
{
@@ -417,7 +470,7 @@ public ref class IEvaluateModelExtendedManaged : IDisposable
417
470
}
418
471
}
419
472
420
- VariableLayout::DataType GetDataType (Microsoft::MSR::CNTK::VariableLayout::DataType dataType)
473
+ VariableLayout::DataType GetDataKind (Microsoft::MSR::CNTK::VariableLayout::DataType dataType)
421
474
{
422
475
switch ((int )dataType)
423
476
{
@@ -430,7 +483,7 @@ public ref class IEvaluateModelExtendedManaged : IDisposable
430
483
}
431
484
}
432
485
433
- VariableLayout::StorageType GetStorageType (Microsoft::MSR::CNTK::VariableLayout::StorageType storageType)
486
+ VariableLayout::StorageType GetStorageKind (Microsoft::MSR::CNTK::VariableLayout::StorageType storageType)
434
487
{
435
488
switch ((int )storageType)
436
489
{
@@ -448,22 +501,22 @@ public ref class IEvaluateModelExtendedManaged : IDisposable
448
501
449
502
// / <summary>Managed float-specific model evaluation class</summary>
450
503
// / <remarks>This class is necessary due to how generics and templates work in CLR</remarks>
451
- public ref class IEvaluateModelExtendedManagedF : IEvaluateModelExtendedManaged <float >
504
+ public ref class ModelEvaluationExtendedF : ModelEvaluationExtended <float >
452
505
{
453
506
public:
454
- IEvaluateModelExtendedManagedF::IEvaluateModelExtendedManagedF ()
455
- : IEvaluateModelExtendedManaged (" GetEvalExtendedF" )
507
+ ModelEvaluationExtendedF::ModelEvaluationExtendedF ()
508
+ : ModelEvaluationExtended (" GetEvalExtendedF" )
456
509
{
457
510
}
458
511
};
459
512
460
513
// / <summary>Managed double-specific model evaluation class</summary>
461
514
// / <remarks>This class is necessary due to how generics and templates work in CLR</remarks>
462
- public ref class IEvaluateModelExtendedManagedD : IEvaluateModelExtendedManaged <double >
515
+ public ref class ModelEvaluationExtendedD : ModelEvaluationExtended <double >
463
516
{
464
517
public:
465
- IEvaluateModelExtendedManagedD::IEvaluateModelExtendedManagedD ()
466
- : IEvaluateModelExtendedManaged (" GetEvalExtendedD" )
518
+ ModelEvaluationExtendedD::ModelEvaluationExtendedD ()
519
+ : ModelEvaluationExtended (" GetEvalExtendedD" )
467
520
{
468
521
}
469
522
};
@@ -472,16 +525,16 @@ public ref class IEvaluateModelExtendedManagedD : IEvaluateModelExtendedManaged<
472
525
// This method tricks the compiler into emitting the methods of the classes
473
526
// Refer to https://msdn.microsoft.com/en-us/library/ms177213.aspx for an
474
527
// explanation to this behavior
475
- void emitExtended ()
528
+ void EmitExtended ()
476
529
{
477
- IEvaluateModelExtendedManagedF f;
530
+ ModelEvaluationExtendedF f;
478
531
f.CreateNetwork (" " );
479
532
f.GetOutputSchema ();
480
533
f.GetInputSchema ();
481
534
f.StartForwardEvaluation (nullptr );
482
535
f.ForwardPass (nullptr , nullptr );
483
536
484
- IEvaluateModelExtendedManagedD d;
537
+ ModelEvaluationExtendedD d;
485
538
d.CreateNetwork (" " );
486
539
d.GetOutputSchema ();
487
540
d.GetInputSchema ();
0 commit comments