1 // =============================================================================
2 // === SuiteSparse_GPURuntime/Source/SuiteSparseGPU_Workspace.cpp ==============
3 // =============================================================================
4
5 // The SuiteSparse_GPURuntime Workspace provides a convenient way to allocate
6 // and free memory on the CPU and/or GPU, and to transfer data between the
7 // CPU and GPU.
8
9 #include "SuiteSparseGPU_Runtime.hpp"
10
11 // -----------------------------------------------------------------------------
12 // Workspace constructor
13 // -----------------------------------------------------------------------------
14
Workspace(size_t _nitems,size_t _size_of_item)15 Workspace::Workspace
16 (
17 size_t _nitems, // number of items to allocate
18 size_t _size_of_item // size of each item
19 )
20 {
21 nitems = _nitems;
22 size_of_item = _size_of_item;
23
24 totalSize = nitems * size_of_item;
25
26 // check for integer overflow
27 if (totalSize != ((double) nitems) * size_of_item)
28 {
29 totalSize = 0 ; // size_t overflow
30 }
31
32 // lazyAllocate = false; // always false, left for future use
33
34 cpuReference = NULL; // no CPU memory allocated yet
35 gpuReference = NULL; // no GPU memory allocated yet
36 }
37
38 // -----------------------------------------------------------------------------
39 // Workspace destructor
40 // -----------------------------------------------------------------------------
41
~Workspace()42 Workspace::~Workspace()
43 {
44 }
45
46 // -----------------------------------------------------------------------------
47 // allocate workspace
48 // -----------------------------------------------------------------------------
49
allocate(size_t nitems,size_t size_of_item,bool doCalloc,bool cpuAlloc,bool gpuAlloc,bool pageLocked)50 Workspace *Workspace::allocate
51 (
52 size_t nitems, // number of items
53 size_t size_of_item, // size of each item
54 bool doCalloc, // true if calloc instead of malloc
55 bool cpuAlloc, // true if allocating on the CPU
56 bool gpuAlloc, // true if allocating on the GPU
57 bool pageLocked // true if pagelocked on the CPU
58 )
59 {
60 // Cannot use calloc directly since that's a member function,
61 // and this is a static member function.
62 Workspace *returner = (Workspace*)
63 Workspace::cpu_calloc (1, sizeof(Workspace), false) ;
64
65 if (returner)
66 {
67 new (returner) Workspace (nitems, size_of_item) ;
68
69 /* Set whether the user wants the address page-locked. */
70 returner->pageLocked = pageLocked ;
71
72 /* Do the allocation & handle any errors. */
73 bool okay = (doCalloc ? returner->ws_calloc (cpuAlloc, gpuAlloc) :
74 returner->ws_malloc (cpuAlloc, gpuAlloc)) ;
75 if (!okay)
76 {
77 returner = Workspace::destroy (returner) ;
78 }
79 }
80
81 return (returner) ;
82 }
83
84 // -----------------------------------------------------------------------------
85 // destroy workspace, freeing memory
86 // -----------------------------------------------------------------------------
87
destroy(Workspace * address)88 Workspace *Workspace::destroy
89 (
90 Workspace *address
91 )
92 {
93 if(address)
94 {
95 address->ws_free(address->cpu(), address->gpu());
96 SuiteSparse_free(address);
97 }
98 return NULL;
99 }
100
101 // -----------------------------------------------------------------------------
102 // ws_malloc: malloc workspace on CPU and/or GPU
103 // -----------------------------------------------------------------------------
104
ws_malloc(bool cpuAlloc,bool gpuAlloc)105 bool Workspace::ws_malloc(bool cpuAlloc, bool gpuAlloc)
106 {
107 if(cpuAlloc)
108 {
109 cpuReference = Workspace::cpu_malloc(nitems, size_of_item, pageLocked);
110 }
111 if(gpuAlloc)
112 {
113 gpuReference = Workspace::gpu_malloc(nitems, size_of_item);
114 }
115
116 bool cpuSideOk = IMPLIES(cpuAlloc, cpuReference != NULL);
117 bool gpuSideOk = IMPLIES(gpuAlloc, gpuReference != NULL)
118 // || lazyAllocate
119 ;
120 return (cpuSideOk && gpuSideOk);
121 }
122
123 // -----------------------------------------------------------------------------
124 // ws_calloc: calloc workspace on CPU and/or GPU
125 // -----------------------------------------------------------------------------
126
ws_calloc(bool cpuAlloc,bool gpuAlloc)127 bool Workspace::ws_calloc(bool cpuAlloc, bool gpuAlloc)
128 {
129 if(cpuAlloc)
130 {
131 cpuReference = Workspace::cpu_calloc(nitems, size_of_item, pageLocked);
132 }
133 if(gpuAlloc)
134 {
135 gpuReference = Workspace::gpu_calloc(nitems, size_of_item);
136 }
137
138 bool cpuSideOk = IMPLIES(cpuAlloc, cpuReference != NULL);
139 bool gpuSideOk = IMPLIES(gpuAlloc, gpuReference != NULL)
140 // || lazyAllocate
141 ;
142 return (cpuSideOk && gpuSideOk);
143 }
144
145 // -----------------------------------------------------------------------------
146 // ws_free: free workspace on CPU and/or GPU
147 // -----------------------------------------------------------------------------
148
ws_free(bool cpuFree,bool gpuFree)149 void Workspace::ws_free(bool cpuFree, bool gpuFree)
150 {
151 if(cpuFree) Workspace::cpu_free(cpuReference, pageLocked);
152 if(gpuFree) Workspace::gpu_free(gpuReference);
153 }
154