@@ -101,25 +101,38 @@ size_t Used<platform::CPUPlace>(const platform::CPUPlace &place) {
101
101
}
102
102
103
103
#ifdef PADDLE_WITH_CUDA
104
- BuddyAllocator *GetGPUBuddyAllocator (int gpu_id) {
105
- static std::once_flag init_flag;
106
- static detail::BuddyAllocator **a_arr = nullptr ;
107
- static std::vector<int > devices;
108
-
109
- std::call_once (init_flag, [gpu_id]() {
110
- devices = platform::GetSelectedDevices ();
111
- int gpu_num = devices.size ();
112
- a_arr = new BuddyAllocator *[gpu_num];
113
-
114
- for (size_t i = 0 ; i < devices.size (); ++i) {
115
- int dev_id = devices[i];
116
- a_arr[i] = nullptr ;
117
- platform::SetDeviceId (dev_id);
118
- a_arr[i] = new BuddyAllocator (std::unique_ptr<detail::SystemAllocator>(
119
- new detail::GPUAllocator (dev_id)),
120
- platform::GpuMinChunkSize (),
121
- platform::GpuMaxChunkSize ());
104
+ class GPUBuddyAllocatorList {
105
+ private:
106
+ GPUBuddyAllocatorList () : devices_(platform::GetSelectedDevices()) {
107
+ auto gpu_num = devices_.size ();
108
+ allocators_.resize (gpu_num);
109
+ init_flags_.reserve (gpu_num);
110
+ for (size_t i = 0 ; i < gpu_num; ++i) {
111
+ init_flags_.emplace_back (new std::once_flag ());
112
+ }
113
+ }
114
+
115
+ static GPUBuddyAllocatorList *CreateNewInstance () {
116
+ return new GPUBuddyAllocatorList ();
117
+ }
118
+
119
+ public:
120
+ static GPUBuddyAllocatorList *Instance () {
121
+ static auto *instance = CreateNewInstance ();
122
+ return instance;
123
+ }
122
124
125
+ BuddyAllocator *Get (int gpu_id) {
126
+ auto pos = std::distance (
127
+ devices_.begin (), std::find (devices_.begin (), devices_.end (), gpu_id));
128
+ PADDLE_ENFORCE_LT (pos, devices_.size ());
129
+
130
+ std::call_once (*init_flags_[pos], [this , pos] {
131
+ platform::SetDeviceId (devices_[pos]);
132
+ allocators_[pos].reset (new BuddyAllocator (
133
+ std::unique_ptr<detail::SystemAllocator>(
134
+ new detail::GPUAllocator (devices_[pos])),
135
+ platform::GpuMinChunkSize (), platform::GpuMaxChunkSize ()));
123
136
VLOG (10 ) << " \n\n NOTE:\n "
124
137
<< " You can set GFlags environment variable "
125
138
<< " 'FLAGS_fraction_of_gpu_memory_to_use' "
@@ -132,13 +145,19 @@ BuddyAllocator *GetGPUBuddyAllocator(int gpu_id) {
132
145
<< FLAGS_initial_gpu_memory_in_mb
133
146
<< " . Current 'FLAGS_reallocate_gpu_memory_in_mb' value is "
134
147
<< FLAGS_reallocate_gpu_memory_in_mb << " \n\n " ;
135
- }
136
- platform::SetDeviceId (gpu_id);
137
- });
148
+ });
149
+
150
+ return allocators_[pos].get ();
151
+ }
138
152
139
- auto pos = std::distance (devices.begin (),
140
- std::find (devices.begin (), devices.end (), gpu_id));
141
- return a_arr[pos];
153
+ private:
154
+ std::vector<int > devices_;
155
+ std::vector<std::unique_ptr<std::once_flag>> init_flags_;
156
+ std::vector<std::unique_ptr<BuddyAllocator>> allocators_;
157
+ };
158
+
159
+ BuddyAllocator *GetGPUBuddyAllocator (int gpu_id) {
160
+ return GPUBuddyAllocatorList::Instance ()->Get (gpu_id);
142
161
}
143
162
#endif
144
163
0 commit comments