| 666 | } |
| 667 | |
| 668 | hipError_t ihipModuleLaunchCooperativeKernelMultiDevice(hipFunctionLaunchParams* launchParamsList, |
| 669 | unsigned int numDevices, unsigned int flags, |
| 670 | uint32_t extFlags) { |
| 671 | int numActiveGPUs = 0; |
| 672 | hipError_t result = hipSuccess; |
| 673 | result = ihipDeviceGetCount(&numActiveGPUs); |
| 674 | |
| 675 | if ((numDevices == 0) || (numDevices > numActiveGPUs)) { |
| 676 | return hipErrorInvalidValue; |
| 677 | } |
| 678 | |
| 679 | if (flags > |
| 680 | (hipCooperativeLaunchMultiDeviceNoPostSync + hipCooperativeLaunchMultiDeviceNoPreSync)) { |
| 681 | return hipErrorInvalidValue; |
| 682 | } |
| 683 | |
| 684 | uint64_t allGridSize = 0; |
| 685 | std::vector<const amd::Device*> mgpu_list(numDevices); |
| 686 | |
| 687 | for (int i = 0; i < numDevices; ++i) { |
| 688 | uint32_t blockDims = 0; |
| 689 | const hipFunctionLaunchParams& launch = launchParamsList[i]; |
| 690 | blockDims = launch.blockDimX * launch.blockDimY * launch.blockDimZ; |
| 691 | allGridSize += launch.gridDimX * launch.gridDimY * launch.gridDimZ * blockDims; |
| 692 | |
| 693 | // Make sure block dimensions are valid |
| 694 | if (0 == blockDims) { |
| 695 | return hipErrorInvalidConfiguration; |
| 696 | } |
| 697 | if (launch.hStream != nullptr) { |
| 698 | // Validate devices to make sure it dosn't have duplicates |
| 699 | hip::Stream* hip_stream = reinterpret_cast<hip::Stream*>(launch.hStream); |
| 700 | auto device = &hip_stream->vdev()->device(); |
| 701 | for (int j = 0; j < numDevices; ++j) { |
| 702 | if (mgpu_list[j] == device) { |
| 703 | return hipErrorInvalidDevice; |
| 704 | } |
| 705 | } |
| 706 | mgpu_list[i] = device; |
| 707 | } else { |
| 708 | return hipErrorInvalidResourceHandle; |
| 709 | } |
| 710 | } |
| 711 | uint64_t prevGridSize = 0; |
| 712 | uint32_t firstDevice = 0; |
| 713 | |
| 714 | // Sync the execution streams on all devices |
| 715 | if ((flags & hipCooperativeLaunchMultiDeviceNoPreSync) == 0) { |
| 716 | for (int i = 0; i < numDevices; ++i) { |
| 717 | hip::Stream* hip_stream = reinterpret_cast<hip::Stream*>(launchParamsList[i].hStream); |
| 718 | hip_stream->finish(); |
| 719 | } |
| 720 | } |
| 721 | |
| 722 | // Grid and Block dimensions should match across devices, as well as sharedMemBytes |
| 723 | for (uint32_t i = 1; i < numDevices; ++i) { |
| 724 | if (launchParamsList[i - 1].gridDimX != launchParamsList[i].gridDimX || |
| 725 | launchParamsList[i - 1].gridDimY != launchParamsList[i].gridDimY || |
no test coverage detected