| 528 | } |
| 529 | |
| 530 | CompNode CompNode::load( |
| 531 | const Locator& locator_physical, const Locator& locator_logical) { |
| 532 | auto phy_device_type_num = static_cast<size_t>(locator_physical.type); |
| 533 | mgb_assert( |
| 534 | phy_device_type_num < NR_DEVICE_TYPE, |
| 535 | "bad device type; maybe new device type is added but " |
| 536 | "NR_DEVICE_TYPE is not modified?"); |
| 537 | if (!g_default_cpu_initialized.test_and_set()) { |
| 538 | // to ensure default_cpu comp node is initialized first, so destructed |
| 539 | // after all other comp nodes |
| 540 | default_cpu(); |
| 541 | } |
| 542 | |
| 543 | CompNode ret; |
| 544 | switch (locator_physical.type) { |
| 545 | case DeviceType::CUDA: |
| 546 | ret = CudaCompNode::load_cuda(locator_physical, locator_logical); |
| 547 | break; |
| 548 | case DeviceType::MULTITHREAD: |
| 549 | case DeviceType::CPU: |
| 550 | ret = CpuCompNode::load_cpu(locator_physical, locator_logical); |
| 551 | break; |
| 552 | case DeviceType::ATLAS: |
| 553 | ret = AtlasCompNode::load_atlas(locator_physical, locator_logical); |
| 554 | break; |
| 555 | case DeviceType::ROCM: |
| 556 | ret = ROCmCompNode::load_rocm(locator_physical, locator_logical); |
| 557 | break; |
| 558 | case DeviceType::CAMBRICON: |
| 559 | ret = CambriconCompNode::load_cambricon(locator_physical, locator_logical); |
| 560 | break; |
| 561 | default: |
| 562 | mgb_throw(MegBrainError, "bad device type"); |
| 563 | } |
| 564 | |
| 565 | if (!g_exit_handler_registered[phy_device_type_num].test_and_set()) { |
| 566 | // register atexit after comp node has been loaded; so ::finalze() can |
| 567 | // be called before other libraries' exit handler |
| 568 | auto err = atexit(&CompNode::finalize); |
| 569 | mgb_assert(!err, "failed to register CompNode::finalize at exit"); |
| 570 | } |
| 571 | |
| 572 | return ret; |
| 573 | } |
| 574 | |
| 575 | void CompNode::finalize() { |
| 576 | #if MGB_CUDA && defined(WIN32) |
no outgoing calls