| 164 | } |
| 165 | |
| 166 | void CompNodeEnv::init_cuda_async( |
| 167 | int dev, CompNode comp_node, const ContinuationCtx<cudaStream_t>& cont) { |
| 168 | m_comp_node = comp_node; |
| 169 | |
| 170 | mgb_assert(!m_user_data_container && !m_async_init_need_wait); |
| 171 | m_cuda_env.device = dev; |
| 172 | m_property.type = DeviceType::CUDA; |
| 173 | MGB_CUDA_CHECK(cudaGetDeviceProperties(&m_cuda_env.device_prop, dev)); |
| 174 | { |
| 175 | auto&& prop = m_cuda_env.device_prop; |
| 176 | m_property.mem_alignment = |
| 177 | std::max(prop.textureAlignment, prop.texturePitchAlignment); |
| 178 | } |
| 179 | |
| 180 | std::atomic_bool tid_set{false}; |
| 181 | auto worker = [this, cont, &tid_set]() { |
| 182 | sys::set_thread_name("async_cuda_init"); |
| 183 | m_async_init_tid = std::this_thread::get_id(); |
| 184 | tid_set.store(true); |
| 185 | bool stream_done = false; |
| 186 | MGB_MARK_USED_VAR(stream_done); |
| 187 | MGB_TRY { |
| 188 | m_cuda_env.activate(); |
| 189 | MGB_CUDA_CHECK(cudaStreamCreateWithFlags( |
| 190 | &m_cuda_env.stream, cudaStreamNonBlocking)); |
| 191 | stream_done = true; |
| 192 | |
| 193 | m_user_data_container = std::make_unique<UserDataContainer>(); |
| 194 | |
| 195 | #if MGB_ENABLE_DEBUG_UTIL |
| 196 | nvtxNameCudaStreamA(m_cuda_env.stream, m_comp_node.to_string().c_str()); |
| 197 | #endif |
| 198 | cont.next(m_cuda_env.stream); |
| 199 | |
| 200 | // megdnn is initialized here; must be placed after cont.next() |
| 201 | // which handles comp node init |
| 202 | mgb_assert( |
| 203 | m_property.mem_alignment == |
| 204 | MegDNNHandle::get(*this).handle()->alignment_requirement()); |
| 205 | auto err = atexit(&CompNode::finalize); |
| 206 | mgb_assert(!err, "failed to register CompNode::finalize at exit"); |
| 207 | } |
| 208 | MGB_CATCH(std::exception & exc, { |
| 209 | mgb_log_error("async cuda init failed: %s", exc.what()); |
| 210 | if (stream_done) { |
| 211 | cudaStreamDestroy(m_cuda_env.stream); |
| 212 | } |
| 213 | cont.err(exc); |
| 214 | throw; |
| 215 | }) |
| 216 | }; |
| 217 | |
| 218 | m_async_init_need_wait = true; |
| 219 | m_async_init_future = std::async(std::launch::async, worker); |
| 220 | while (!tid_set.load()) |
| 221 | std::this_thread::yield(); |
| 222 | mgb_assert(m_async_init_tid != std::this_thread::get_id()); |
| 223 | } |
no test coverage detected