| 200 | |
| 201 | template<typename Dtype> |
| 202 | P2PSync<Dtype>::P2PSync(shared_ptr<Solver<Dtype> > root_solver, |
| 203 | P2PSync<Dtype>* parent, const SolverParameter& param) |
| 204 | : GPUParams<Dtype>(root_solver, param.device_id()), |
| 205 | parent_(parent), |
| 206 | children_(), |
| 207 | queue_(), |
| 208 | initial_iter_(root_solver->iter()), |
| 209 | solver_() { |
| 210 | #ifndef CPU_ONLY |
| 211 | int initial_device; |
| 212 | CUDA_CHECK(cudaGetDevice(&initial_device)); |
| 213 | const int self = param.device_id(); |
| 214 | CUDA_CHECK(cudaSetDevice(self)); |
| 215 | |
| 216 | if (parent == NULL) { |
| 217 | solver_ = root_solver; |
| 218 | } else { |
| 219 | Caffe::set_root_solver(false); |
| 220 | solver_.reset(new WorkerSolver<Dtype>(param, root_solver.get())); |
| 221 | Caffe::set_root_solver(true); |
| 222 | } |
| 223 | this->configure(solver_.get()); |
| 224 | solver_->add_callback(this); |
| 225 | |
| 226 | if (parent) { |
| 227 | // Enable p2p access between devices |
| 228 | const int peer = parent->solver_->param().device_id(); |
| 229 | int access; |
| 230 | CUDA_CHECK(cudaDeviceCanAccessPeer(&access, self, peer)); |
| 231 | if (access) { |
| 232 | CUDA_CHECK(cudaDeviceEnablePeerAccess(peer, 0)); |
| 233 | } else { |
| 234 | LOG(INFO)<< "GPU " << self << " does not have p2p access to GPU " << peer; |
| 235 | } |
| 236 | // Allocate receiving buffer on parent |
| 237 | CUDA_CHECK(cudaSetDevice(peer)); |
| 238 | CUDA_CHECK(cudaMalloc(&parent_grads_, size_ * sizeof(Dtype))); |
| 239 | CUDA_CHECK(cudaSetDevice(self)); |
| 240 | } |
| 241 | |
| 242 | CUDA_CHECK(cudaSetDevice(initial_device)); |
| 243 | #else |
| 244 | NO_GPU; |
| 245 | #endif |
| 246 | } |
| 247 | |
| 248 | template<typename Dtype> |
| 249 | P2PSync<Dtype>::~P2PSync() { |
nothing calls this directly
no test coverage detected