-
Notifications
You must be signed in to change notification settings - Fork 83
/
Copy pathBasicTypesStructAsTypes.cs
2627 lines (2388 loc) · 106 KB
/
BasicTypesStructAsTypes.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Copyright (c) 2023, Michael Kunz and Artic Imaging SARL. All rights reserved.
// http://kunzmi.github.io/managedCuda
//
// This file is part of ManagedCuda.
//
// Commercial License Usage
// Licensees holding valid commercial ManagedCuda licenses may use this
// file in accordance with the commercial license agreement provided with
// the Software or, alternatively, in accordance with the terms contained
// in a written agreement between you and Artic Imaging SARL. For further
// information contact us at [email protected].
//
// GNU General Public License Usage
// Alternatively, this file may be used under the terms of the GNU General
// Public License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// ManagedCuda is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ManagedCuda.BasicTypes
{
#region Struct as Types
/// <summary>
/// CUDA array
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct CUarray
{
/// <summary>
///
/// </summary>
public IntPtr Pointer;
/// <summary>
/// Returns the memory requirements of a CUDA array
/// </summary>
public CudaArrayMemoryRequirements GetMemoryRequirements(CUdevice device)
{
CudaArrayMemoryRequirements temp = new CudaArrayMemoryRequirements();
CUResult res = DriverAPINativeMethods.ArrayManagement.cuArrayGetMemoryRequirements(ref temp, this, device);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuArrayGetMemoryRequirements", res));
if (res != CUResult.Success) throw new CudaException(res);
return temp;
}
}
/// <summary>
/// CUDA linker
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct CUlinkState
{
/// <summary>
///
/// </summary>
public IntPtr Pointer;
}
/// <summary>
/// CUDA mipmapped array
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct CUmipmappedArray
{
/// <summary>
///
/// </summary>
public IntPtr Pointer;
/// <summary>
/// Returns the memory requirements of a CUDA array
/// </summary>
public CudaArrayMemoryRequirements GetMemoryRequirements(CUdevice device)
{
CudaArrayMemoryRequirements temp = new CudaArrayMemoryRequirements();
CUResult res = DriverAPINativeMethods.ArrayManagement.cuMipmappedArrayGetMemoryRequirements(ref temp, this, device);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuMipmappedArrayGetMemoryRequirements", res));
if (res != CUResult.Success) throw new CudaException(res);
return temp;
}
}
/// <summary>
/// Cuda context
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct CUcontext
{
/// <summary>
///
/// </summary>
public IntPtr Pointer;
/// <summary>
/// Get context resources<para/>
/// Get the \p type resources available to the context represented by \p hCtx
/// Note: The API is not supported on 32-bit platforms.
/// </summary>
public CUdevResource GetDevResource(CUdevResourceType type)
{
CUdevResource value = new CUdevResource();
CUResult res = DriverAPINativeMethods.GreenContextAPI.cuCtxGetDevResource(this, ref value, type);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuCtxGetDevResource", res));
if (res != CUResult.Success) throw new CudaException(res);
return value;
}
}
/// <summary>
/// Cuda device
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct CUdevice
{
/// <summary>
///
/// </summary>
public int Pointer;
/// <summary>
///
/// </summary>
public CUdevice(int deviceId)
{
CUResult res;
CUdevice temp = new CUdevice();
res = DriverAPINativeMethods.DeviceManagement.cuDeviceGet(ref temp, deviceId);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuDeviceGet", res));
if (res == CUResult.ErrorNotInitialized)
{
res = DriverAPINativeMethods.cuInit(CUInitializationFlags.None);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuInit", res));
if (res != CUResult.Success)
throw new CudaException(res);
res = DriverAPINativeMethods.DeviceManagement.cuDeviceGet(ref temp, deviceId);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuDeviceGet", res));
if (res != CUResult.Success)
throw new CudaException(res);
}
else if (res != CUResult.Success)
throw new CudaException(res);
this = temp;
}
/// <summary>
/// Device that represents the CPU
/// </summary>
public static CUdevice CPU
{
get
{
CUdevice cpu = new CUdevice();
cpu.Pointer = -1;
return cpu;
}
}
/// <summary>
/// Device that represents an invalid device
/// </summary>
public static CUdevice Invalid
{
get
{
CUdevice invalid = new CUdevice();
invalid.Pointer = -2;
return invalid;
}
}
/// <summary>
/// Sets the current memory pool of a device<para/>
/// The memory pool must be local to the specified device.
/// ::cuMemAllocAsync allocates from the current mempool of the provided stream's device.
/// By default, a device's current memory pool is its default memory pool.
/// <para/>
/// note Use ::cuMemAllocFromPoolAsync to specify asynchronous allocations from a device different than the one the stream runs on.
/// </summary>
public void SetMemoryPool(CudaMemoryPool memPool)
{
CUResult res = DriverAPINativeMethods.DeviceManagement.cuDeviceSetMemPool(this, memPool.MemoryPool);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuDeviceSetMemPool", res));
if (res != CUResult.Success) throw new CudaException(res);
}
/// <summary>
/// Gets the current memory pool of the CUdevice.
/// </summary>
public CudaMemoryPool GetMemoryPool()
{
return new CudaMemoryPool(this, false);
}
/// <summary>
/// Gets the default memory pool of the CUdevice.
/// </summary>
public CudaMemoryPool GetDefaultMemoryPool()
{
return new CudaMemoryPool(this, true);
}
/// <summary>
/// Return an UUID for the device (11.4+)<para/>
/// Returns 16-octets identifing the device \p dev in the structure
/// pointed by the \p uuid.If the device is in MIG mode, returns its
/// MIG UUID which uniquely identifies the subscribed MIG compute instance.
/// Returns 16-octets identifing the device \p dev in the structure pointed by the \p uuid.
/// </summary>
public CUuuid Uuid
{
get
{
CUuuid uuid = new CUuuid();
CUResult res = DriverAPINativeMethods.DeviceManagement.cuDeviceGetUuid_v2(ref uuid, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuDeviceGetUuid_v2", res));
if (res != CUResult.Success) throw new CudaException(res);
return uuid;
}
}
/// <summary>
/// Returns information about the execution affinity support of the device.<para/>
/// Returns in \p *pi whether execution affinity type \p type is supported by device \p dev.<para/>
/// The supported types are:<para/>
/// - ::CU_EXEC_AFFINITY_TYPE_SM_COUNT: 1 if context with limited SMs is supported by the device,
/// or 0 if not;
/// </summary>
public bool GetExecAffinitySupport(CUexecAffinityType type)
{
int pi = 0;
CUResult res = DriverAPINativeMethods.DeviceManagement.cuDeviceGetExecAffinitySupport(ref pi, type, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuDeviceGetExecAffinitySupport", res));
if (res != CUResult.Success) throw new CudaException(res);
return pi > 0;
}
/// <summary>
/// Free unused memory that was cached on the specified device for use with graphs back to the OS.<para/>
/// Blocks which are not in use by a graph that is either currently executing or scheduled to execute are freed back to the operating system.
/// </summary>
public void GraphMemTrim()
{
CUResult res = DriverAPINativeMethods.GraphManagment.cuDeviceGraphMemTrim(this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuDeviceGraphMemTrim", res));
if (res != CUResult.Success) throw new CudaException(res);
}
/// <summary>
/// Set asynchronous allocation attributes related to graphs<para/>
/// Valid attributes are:<para/>
/// - ::CU_GRAPH_MEM_ATTR_USED_MEM_HIGH: High watermark of memory, in bytes, associated with graphs since the last time it was reset.High watermark can only be reset to zero.<para/>
/// - ::CU_GRAPH_MEM_ATTR_RESERVED_MEM_HIGH: High watermark of memory, in bytes, currently allocated for use by the CUDA graphs asynchronous allocator.
/// </summary>
public void SetGraphMemAttribute(CUgraphMem_attribute attr, ulong value)
{
CUResult res = DriverAPINativeMethods.GraphManagment.cuDeviceSetGraphMemAttribute(this, attr, ref value);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuDeviceSetGraphMemAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
}
/// <summary>
/// Query asynchronous allocation attributes related to graphs<para/>
/// Valid attributes are:<para/>
/// - ::CU_GRAPH_MEM_ATTR_USED_MEM_CURRENT: Amount of memory, in bytes, currently associated with graphs<para/>
/// - ::CU_GRAPH_MEM_ATTR_USED_MEM_HIGH: High watermark of memory, in bytes, associated with graphs since the last time it was reset.High watermark can only be reset to zero.<para/>
/// - ::CU_GRAPH_MEM_ATTR_RESERVED_MEM_CURRENT: Amount of memory, in bytes, currently allocated for use by the CUDA graphs asynchronous allocator.<para/>
/// - ::CU_GRAPH_MEM_ATTR_RESERVED_MEM_HIGH: High watermark of memory, in bytes, currently allocated for use by the CUDA graphs asynchronous allocator.
/// </summary>
public ulong GetGraphMemAttribute(CUgraphMem_attribute attr)
{
ulong value = 0;
CUResult res = DriverAPINativeMethods.GraphManagment.cuDeviceGetGraphMemAttribute(this, attr, ref value);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuDeviceGetGraphMemAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return value;
}
#region operators
/// <summary>
///
/// </summary>
/// <param name="src"></param>
/// <param name="value"></param>
/// <returns></returns>
public static bool operator ==(CUdevice src, CUdevice value)
{
return src.Pointer == value.Pointer;
}
/// <summary>
///
/// </summary>
/// <param name="src"></param>
/// <param name="value"></param>
/// <returns></returns>
public static bool operator !=(CUdevice src, CUdevice value)
{
return src.Pointer != value.Pointer;
}
#endregion
#region Override Methods
/// <summary>
/// Returns true if both objects are of type CUdevice and if both Pointer member are equal.
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(object obj)
{
if (!(obj is CUdevice)) return false;
CUdevice value = (CUdevice)obj;
return this.Pointer.Equals(value.Pointer);
}
/// <summary>
/// Overrides object.GetHashCode()
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
return Pointer.GetHashCode();
}
/// <summary>
/// override ToString()
/// </summary>
/// <returns></returns>
public override string ToString()
{
return Pointer.ToString();
}
#endregion
/// <summary>
/// Get device resources<para/>
/// Get the \p type resources available to the \p device.<para/>
/// This may often be the starting point for further partitioning or configuring of resources.<para/>
/// Note: The API is not supported on 32-bit platforms.
/// </summary>
public CUdevResource GetDevResource(CUdevResourceType type)
{
CUdevResource value = new CUdevResource();
CUResult res = DriverAPINativeMethods.GreenContextAPI.cuDeviceGetDevResource(this, ref value, type);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuDeviceGetDevResource", res));
if (res != CUResult.Success) throw new CudaException(res);
return value;
}
}
/// <summary>
/// Pointer to CUDA device memory
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct CUdeviceptr
{
/// <summary>
///
/// </summary>
public SizeT Pointer;
#region operators
/// <summary>
///
/// </summary>
/// <param name="src"></param>
/// <returns></returns>
public static implicit operator ulong(CUdeviceptr src)
{
return src.Pointer;
}
/// <summary>
///
/// </summary>
/// <param name="src"></param>
/// <returns></returns>
public static explicit operator CUdeviceptr(SizeT src)
{
CUdeviceptr udeviceptr = new CUdeviceptr();
udeviceptr.Pointer = src;
return udeviceptr;
}
/// <summary>
///
/// </summary>
/// <param name="src"></param>
/// <param name="value"></param>
/// <returns></returns>
public static CUdeviceptr operator +(CUdeviceptr src, SizeT value)
{
CUdeviceptr udeviceptr = new CUdeviceptr();
udeviceptr.Pointer = src.Pointer + value;
return udeviceptr;
}
/// <summary>
///
/// </summary>
/// <param name="src"></param>
/// <param name="value"></param>
/// <returns></returns>
public static CUdeviceptr operator -(CUdeviceptr src, SizeT value)
{
CUdeviceptr udeviceptr = new CUdeviceptr();
udeviceptr.Pointer = src.Pointer - value;
return udeviceptr;
}
/// <summary>
///
/// </summary>
/// <param name="src"></param>
/// <param name="value"></param>
/// <returns></returns>
public static bool operator ==(CUdeviceptr src, CUdeviceptr value)
{
return src.Pointer == value.Pointer;
}
/// <summary>
///
/// </summary>
/// <param name="src"></param>
/// <param name="value"></param>
/// <returns></returns>
public static bool operator !=(CUdeviceptr src, CUdeviceptr value)
{
return src.Pointer != value.Pointer;
}
#endregion
#region Override Methods
/// <summary>
/// Returns true if both objects are of type CUdeviceptr and if both Pointer member is equal.
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(object obj)
{
if (!(obj is CUdeviceptr)) return false;
CUdeviceptr value = (CUdeviceptr)obj;
return this.Pointer.Equals(value.Pointer);
}
/// <summary>
/// Overrides object.GetHashCode()
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
return base.GetHashCode();
}
/// <summary>
/// override ToString()
/// </summary>
/// <returns></returns>
public override string ToString()
{
return Pointer.ToString();
}
#endregion
#region constructors
/// <summary>
///
/// </summary>
/// <param name="pointer"></param>
public CUdeviceptr(SizeT pointer)
{
Pointer = pointer;
}
#endregion
#region GetAttributeMethods
/// <summary>
/// The <see cref="CUcontext"/> on which a pointer was allocated or registered
/// </summary>
public CUcontext AttributeContext
{
get
{
CUcontext ret = new CUcontext();
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.Context, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret;
}
}
/// <summary>
/// The <see cref="CUMemoryType"/> describing the physical location of a pointer
/// </summary>
public CUMemoryType AttributeMemoryType
{
get
{
CUMemoryType ret = new CUMemoryType();
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.MemoryType, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret;
}
}
/// <summary>
/// The address at which a pointer's memory may be accessed on the device <para/>
/// Except in the exceptional disjoint addressing cases, the value returned will equal the input value.
/// </summary>
public CUdeviceptr AttributeDevicePointer
{
get
{
CUdeviceptr ret = new CUdeviceptr();
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.DevicePointer, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret;
}
}
/// <summary>
/// The address at which a pointer's memory may be accessed on the host
/// </summary>
public IntPtr AttributeHostPointer
{
get
{
IntPtr ret = new IntPtr();
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.HostPointer, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret;
}
}
/// <summary>
/// A pair of tokens for use with the nv-p2p.h Linux kernel interface
/// </summary>
public CudaPointerAttributeP2PTokens AttributeP2PTokens
{
get
{
CudaPointerAttributeP2PTokens ret = new CudaPointerAttributeP2PTokens();
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.P2PTokens, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret;
}
}
/// <summary>
/// Synchronize every synchronous memory operation initiated on this region
/// </summary>
public bool AttributeSyncMemops
{
get
{
int ret = 0;
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.SyncMemops, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret != 0;
}
set
{
int val = value ? 1 : 0;
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerSetAttribute(ref val, CUPointerAttribute.SyncMemops, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerSetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
}
}
/// <summary>
/// A process-wide unique ID for an allocated memory region
/// </summary>
public ulong AttributeBufferID
{
get
{
ulong ret = 0;
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.BufferID, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret;
}
}
/// <summary>
/// Indicates if the pointer points to managed memory
/// </summary>
public bool AttributeIsManaged
{
get
{
int ret = 0;
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.IsManaged, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret != 0;
}
}
/// <summary>
/// A device ordinal of a device on which a pointer was allocated or registered
/// </summary>
public int AttributeDeviceOrdinal
{
get
{
int ret = 0;
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.DeviceOrdinal, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret;
}
}
/// <summary>
/// 1 if this pointer maps to an allocation that is suitable for ::cudaIpcGetMemHandle, 0 otherwise
/// </summary>
public bool AttributeIsLegacyCudaIPCCapable
{
get
{
int ret = 0;
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.IsLegacyCudaIPCCapable, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret != 0;
}
}
/// <summary>
/// Starting address for this requested pointer
/// </summary>
public CUdeviceptr AttributeRangeStartAddr
{
get
{
CUdeviceptr ret = new CUdeviceptr();
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.RangeStartAddr, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret;
}
}
/// <summary>
/// Size of the address range for this requested pointer
/// </summary>
public SizeT AttributeRangeSize
{
get
{
ulong ret = 0;
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.RangeSize, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret;
}
}
/// <summary>
/// 1 if this pointer is in a valid address range that is mapped to a backing allocation, 0 otherwise
/// </summary>
public bool AttributeMapped
{
get
{
int ret = 0;
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.Mapped, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret != 0;
}
}
/// <summary>
/// Bitmask of allowed ::CUmemAllocationHandleType for this allocation
/// </summary>
public CUmemAllocationHandleType AttributeAllowedHandleTypes
{
get
{
int ret = 0;
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.AllowedHandleTypes, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return (CUmemAllocationHandleType)ret;
}
}
/// <summary>
/// 1 if the memory this pointer is referencing can be used with the GPUDirect RDMA API
/// </summary>
public bool AttributeIsGPUDirectRDMACapable
{
get
{
int ret = 0;
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.IsGPUDirectRDMACapable, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret != 0;
}
}
/// <summary>
/// Returns the access flags the device associated with the current context has on the corresponding memory referenced by the pointer given
/// </summary>
public bool AttributeAccessFlags
{
get
{
int ret = 0;
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.AccessFlags, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret != 0;
}
}
/// <summary>
/// Returns the mempool handle for the allocation if it was allocated from a mempool. Otherwise returns NULL.
/// </summary>
public CUmemoryPool AttributeMempoolHandle
{
get
{
IntPtr temp = new IntPtr();
CUmemoryPool ret = new CUmemoryPool();
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref temp, CUPointerAttribute.MempoolHandle, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
ret.Pointer = temp;
return ret;
}
}
/// <summary>
/// Size of the actual underlying mapping that the pointer belongs to
/// </summary>
public SizeT AttributeMappingSize
{
get
{
ulong ret = 0;
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.MappingSize, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret;
}
}
/// <summary>
/// The start address of the mapping that the pointer belongs to
/// </summary>
public IntPtr AttributeBaseAddr
{
get
{
IntPtr ret = new IntPtr();
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.BaseAddr, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret;
}
}
/// <summary>
/// A process-wide unique id corresponding to the physical allocation the pointer belongs to
/// </summary>
public ulong AttributeMemoryBlockID
{
get
{
ulong ret = 0;
CUResult res = DriverAPINativeMethods.MemoryManagement.cuPointerGetAttribute(ref ret, CUPointerAttribute.MemoryBlockID, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuPointerGetAttribute", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret;
}
}
#endregion
}
/// <summary>
/// Cuda event
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct CUevent
{
/// <summary>
///
/// </summary>
public IntPtr Pointer;
}
/// <summary>
/// Cuda function / kernel
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct CUfunction
{
/// <summary>
///
/// </summary>
public IntPtr Pointer;
/// <summary>
/// Returns a module handle<para/>
/// Returns in \p *hmod the handle of the module that function \p hfunc
/// is located in. The lifetime of the module corresponds to the lifetime of
/// the context it was loaded in or until the module is explicitly unloaded.<para/>
/// The CUDA runtime manages its own modules loaded into the primary context.
/// If the handle returned by this API refers to a module loaded by the CUDA runtime,
/// calling ::cuModuleUnload() on that module will result in undefined behavior.
/// </summary>
public CUmodule GetModule()
{
CUmodule temp = new CUmodule();
CUResult res = DriverAPINativeMethods.FunctionManagement.cuFuncGetModule(ref temp, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuFuncGetModule", res));
if (res != CUResult.Success) throw new CudaException(res);
return temp;
}
/// <summary>
/// Returns the function name for a ::CUfunction handle<para/>
/// Returns in \p **name the function name associated with the function handle \p hfunc.<para/>
/// The function name is returned as a null-terminated string. The returned name is only
/// valid when the function handle is valid.If the module is unloaded or reloaded, one
/// must call the API again to get the updated name.This API may return a mangled name if
/// the function is not declared as having C linkage.If either \p** name or \p hfunc
/// is NULL, ::CUDA_ERROR_INVALID_VALUE is returned.
/// </summary>
public string GetName()
{
string name = string.Empty;
CUResult res = DriverAPINativeMethods.FunctionManagement.cuFuncGetName(ref name, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuFuncGetName", res));
if (res != CUResult.Success) throw new CudaException(res);
return name;
}
#if (NETCOREAPP) //old .net framework doesn't support tupels
/// <summary>
/// Returns the offset and size of a kernel parameter in the device-side parameter layout<para/>
/// Queries the kernel parameter at \p paramIndex into \p func's list of parameters, and returns
/// in \p paramOffset and \p paramSize the offset and size, respectively, where the parameter
/// will reside in the device-side parameter layout.This information can be used to update kernel
/// node parameters from the device via ::cudaGraphKernelNodeSetParam() and
/// ::cudaGraphKernelNodeUpdatesApply(). \p paramIndex must be less than the number of parameters
/// that \p func takes. \p paramSize can be set to NULL if only the parameter offset is desired.
/// </summary>
/// <param name="paramIndex">The parameter index to query</param>
public (SizeT, SizeT) GetParamInfo(SizeT paramIndex)
{
SizeT offset = 0;
SizeT size = 0;
CUResult res = DriverAPINativeMethods.FunctionManagement.cuFuncGetParamInfo(this, paramIndex, ref offset, ref size);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuFuncGetParamInfo", res));
if (res != CUResult.Success) throw new CudaException(res);
return (offset, size);
}
#endif
/// <summary>
/// Returns if the function is loaded<para/>
/// </summary>
public CUfunctionLoadingState IsLoaded
{
get
{
CUfunctionLoadingState ret = new CUfunctionLoadingState();
CUResult res = DriverAPINativeMethods.FunctionManagement.cuFuncIsLoaded(ref ret, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuFuncIsLoaded", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret;
}
}
/// <summary>
/// Loads a function<para/>
/// Finalizes function loading for \p function.Calling this API with afully loaded function has no effect.
/// </summary>
public void Load()
{
CUResult res = DriverAPINativeMethods.FunctionManagement.cuFuncLoad(this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuFuncLoad", res));
if (res != CUResult.Success) throw new CudaException(res);
}
}
/// <summary>
/// Cuda module
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct CUmodule
{
/// <summary>
///
/// </summary>
public IntPtr Pointer;
/// <summary>
/// Query lazy loading mode<para/>
/// Returns lazy loading mode. Module loading mode is controlled by CUDA_MODULE_LOADING env variable
/// </summary>
public static CUmoduleLoadingMode GetLoadingMode
{
get
{
CUmoduleLoadingMode ret = new CUmoduleLoadingMode();
CUResult res = DriverAPINativeMethods.ModuleManagement.cuModuleGetLoadingMode(ref ret);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuModuleGetLoadingMode", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret;
}
}
/// <summary>
/// Returns the number of functions within the module
/// </summary>
public uint FunctionCount
{
get
{
uint fcount = 0;
CUResult res = DriverAPINativeMethods.ModuleManagement.cuModuleGetFunctionCount(ref fcount, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuModuleGetFunctionCount", res));
if (res != CUResult.Success) throw new CudaException(res);
return fcount;
}
}
/// <summary>
/// Returns the function handles within a module.<para/>
/// Returns in \p functions a maximum number of \p numFunctions function handles within \p mod.When
/// function loading mode is set to LAZY the function retrieved may be partially loaded. The loading
/// state of a function can be queried using ::cuFunctionIsLoaded. CUDA APIs may load the function
/// automatically when called with partially loaded function handle which may incur additional
/// latency.Alternatively, ::cuFunctionLoad can be used to explicitly load a function. The returned
/// function handles become invalid when the module is unloaded.
/// </summary>
/// <param name="functions">Buffer where the function handles are returned to</param>
/// <param name="numFunctions">Maximum number of function handles may be returned to the buffer</param>
public void EnumerateFunctions(CUfunction[] functions, uint numFunctions)
{
CUResult res = DriverAPINativeMethods.ModuleManagement.cuModuleEnumerateFunctions(functions, numFunctions, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuModuleEnumerateFunctions", res));
if (res != CUResult.Success) throw new CudaException(res);
}
/// <summary>
/// Returns all the function handles within a module.<para/>
/// When
/// function loading mode is set to LAZY the function retrieved may be partially loaded. The loading
/// state of a function can be queried using ::cuFunctionIsLoaded. CUDA APIs may load the function
/// automatically when called with partially loaded function handle which may incur additional
/// latency.Alternatively, ::cuFunctionLoad can be used to explicitly load a function. The returned
/// function handles become invalid when the module is unloaded.
/// </summary>
public CUfunction[] EnumerateFunctions()
{
uint functionCount = FunctionCount;
CUfunction[] ret = new CUfunction[functionCount];
CUResult res = DriverAPINativeMethods.ModuleManagement.cuModuleEnumerateFunctions(ret, functionCount, this);
Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuModuleEnumerateFunctions", res));
if (res != CUResult.Success) throw new CudaException(res);
return ret;
}
}