@@ -317,9 +317,15 @@ hipError_t FatBinaryInfo::ExtractFatBinaryUsingCOMGR(const std::vector<hip::Devi
317317 std::string device_name = device->devices ()[0 ]->isa ().isaName ();
318318 unique_isa_names.insert ({device_name, std::make_pair<size_t , size_t >(0 , 0 )});
319319 }
320- // Add the spirv target
321- const std::string spirv_isa_name = " spirv64-amd-amdhsa--amdgcnspirv" ;
322- unique_isa_names.insert ({spirv_isa_name, std::make_pair<size_t , size_t >(0 , 0 )});
320+
321+ // there are two spirv targets, spirv64-amd-amdhsa--amdgcnspirv and
322+ // spirv64-amd-amdhsa-unknown-amdgcnspirv.
323+ // eventually we will remove spirv64-amd-amdhsa--amdgcnspirv
324+ const std::vector<std::string> spirv_isa_names = {" spirv64-amd-amdhsa--amdgcnspirv" ,
325+ " spirv64-amd-amdhsa-unknown-amdgcnspirv" };
326+ for (const auto & spirv_isa_name : spirv_isa_names) {
327+ unique_isa_names.insert ({spirv_isa_name, std::make_pair<size_t , size_t >(0 , 0 )});
328+ }
323329
324330 // Create a query list using COMGR info for unique ISAs.
325331 std::vector<amd_comgr_code_object_info_t > query_list_array;
@@ -347,45 +353,36 @@ hipError_t FatBinaryInfo::ExtractFatBinaryUsingCOMGR(const std::vector<hip::Devi
347353 static_cast <size_t >(item.offset ));
348354 }
349355
350- // if we have SPIRV isa, we will use Comgr to create isa for all devices.
351- auto spirv_isa_handle = unique_isa_names.find (spirv_isa_name);
352- bool spirv_isa_found = spirv_isa_handle->second .first != 0 ;
353-
354- if (!spirv_isa_found) {
355- for (auto device : devices) {
356- std::string device_name = device->devices ()[0 ]->isa ().isaName ();
357- auto dev_it = unique_isa_names.find (device_name);
358- // If the size is 0, then Comgr API could not find the CO for this GPU device/ISA
359- if (dev_it->second .first == 0 ) {
360- LogPrintfError (" Cannot find CO in the bundle %s for ISA: %s" , fname_.c_str (),
361- device_name.c_str ());
362- hip_status = hipErrorNoBinaryForGpu;
363- ListAllDeviceWithNoCOFromBundle (unique_isa_names);
364- break ;
365- }
366- guarantee (unique_isa_names.cend () != dev_it,
367- " Cannot find the device name in the unique device name" );
368- fatbin_dev_info_[device->deviceId ()] = new FatBinaryDeviceInfo (
369- reinterpret_cast <address>(const_cast <void *>(image_)) + dev_it->second .second ,
370- dev_it->second .first , dev_it->second .second );
371- fatbin_dev_info_[device->deviceId ()]->program_ = new amd::Program (*(device->asContext ()));
356+ bool spirv_isa_found = false ;
357+ decltype (unique_isa_names.begin ()) spirv_isa_handle;
358+ for (const auto & spirv_isa_name : spirv_isa_names) {
359+ auto iter = unique_isa_names.find (spirv_isa_name);
360+ if (iter->second .first != 0 ) {
361+ spirv_isa_found = true ;
362+ spirv_isa_handle = iter;
372363 }
373- } else {
374- LogPrintfDebug (" %s" , " SPIRV isa found" );
364+ }
365+
366+ bool compile_spv_bitcode_res = false ;
367+ std::once_flag spirv_to_bc_flag;
375368
376- comgr_helper::ComgrDataSetUniqueHandle spirv_data_set, bc_data_set;
369+ comgr_helper::ComgrDataSetUniqueHandle bc_data_set;
370+ std::unordered_map<std::string, std::pair<char *, size_t >> compiled_co; // code object cache
371+
372+ auto compile_spv_bitcode = [&]() {
373+ comgr_helper::ComgrDataSetUniqueHandle spirv_data_set;
377374 comgr_helper::ComgrDataUniqueHandle spirv_data;
378375 comgr_helper::ComgrActionInfoUniqueHandle action;
379376
380377 if (comgr_status = spirv_data_set.Create (); comgr_status != AMD_COMGR_STATUS_SUCCESS) {
381378 LogError (" Failed to create SPIRV Data set" );
382- break ;
379+ return ;
383380 }
384381
385382 if (comgr_status = spirv_data.Create (AMD_COMGR_DATA_KIND_SPIRV);
386383 comgr_status != AMD_COMGR_STATUS_SUCCESS) {
387384 LogError (" Failed to create SPIRV Data" );
388- break ;
385+ return ;
389386 }
390387
391388 if (comgr_status =
@@ -394,43 +391,64 @@ hipError_t FatBinaryInfo::ExtractFatBinaryUsingCOMGR(const std::vector<hip::Devi
394391 spirv_isa_handle->second .second /* buffer */ );
395392 comgr_status != AMD_COMGR_STATUS_SUCCESS) {
396393 LogError (" Failed to assign data in comgr" );
397- break ;
394+ return ;
398395 }
399396
400397 if (comgr_status = amd::Comgr::set_data_name (spirv_data.get (), " hip_code_object.spv" );
401398 comgr_status != AMD_COMGR_STATUS_SUCCESS) {
402399 LogError (" Failed to set data name" );
403- break ;
400+ return ;
404401 }
405402
406403 if (comgr_status = amd::Comgr::data_set_add (spirv_data_set.get (), spirv_data.get ());
407404 comgr_status != AMD_COMGR_STATUS_SUCCESS) {
408405 LogError (" Failed to add spir data" );
409- break ;
406+ return ;
410407 }
411408
412409 if (comgr_status = action.Create (); comgr_status != AMD_COMGR_STATUS_SUCCESS) {
413410 LogError (" Failed to create action" );
414- break ;
411+ return ;
415412 }
416413
417414 if (comgr_status = bc_data_set.Create (); comgr_status != AMD_COMGR_STATUS_SUCCESS) {
418415 LogError (" Failed to create bitcode data set" );
419- break ;
416+ return ;
420417 }
421418
422419 if (comgr_status = amd::Comgr::do_action (AMD_COMGR_ACTION_TRANSLATE_SPIRV_TO_BC, action.get (),
423420 spirv_data_set.get (), bc_data_set.get ());
424421 comgr_status != AMD_COMGR_STATUS_SUCCESS) {
425422 LogError (" Failed to compile to ll" );
426- break ;
423+ return ;
427424 }
425+ compile_spv_bitcode_res = true ;
426+ };
428427
429- // System might report multiple devices of same name, we do not want to recompile for all
430- // these. store code objects after compiling them to reuse.
431- std::unordered_map<std::string, std::pair<char *, size_t >> compiled_co;
428+ LogPrintfInfo (" Searching for code objects, HIP_FORCE_SPIRV_CODEOBJECT: %d" ,
429+ HIP_FORCE_SPIRV_CODEOBJECT);
430+
431+ for (auto device : devices) {
432+ std::string device_name = device->devices ()[0 ]->isa ().isaName ();
433+ auto dev_it = unique_isa_names.find (device_name);
434+ // If the size is not 0, that means we found the native isa code object
435+ if (dev_it->second .first != 0 && !HIP_FORCE_SPIRV_CODEOBJECT) {
436+ LogPrintfInfo (" Using Native code object: %s" , device->devices ()[0 ]->isa ().targetId ());
437+ guarantee (unique_isa_names.cend () != dev_it,
438+ " Cannot find the device name in the unique device name" );
439+ fatbin_dev_info_[device->deviceId ()] = new FatBinaryDeviceInfo (
440+ reinterpret_cast <address>(const_cast <void *>(image_)) + dev_it->second .second ,
441+ dev_it->second .first , dev_it->second .second );
442+ fatbin_dev_info_[device->deviceId ()]->program_ = new amd::Program (*(device->asContext ()));
443+ } else if (spirv_isa_found) {
444+ // Compile to bitcode once
445+ std::call_once (spirv_to_bc_flag, compile_spv_bitcode);
446+
447+ if (!compile_spv_bitcode_res) {
448+ hip_status = hipErrorInvalidValue;
449+ break ;
450+ }
432451
433- for (auto device : devices) {
434452 std::string target_id = device->devices ()[0 ]->isa ().targetId ();
435453 if (auto code_iter = compiled_co.find (target_id); code_iter != compiled_co.end ()) {
436454 // We have already compiled for it, lets reuse the code object
@@ -451,7 +469,6 @@ hipError_t FatBinaryInfo::ExtractFatBinaryUsingCOMGR(const std::vector<hip::Devi
451469 break ;
452470 }
453471
454- // TODO: do this for all devices
455472 if (comgr_status = amd::Comgr::action_info_set_isa_name (reloc_action.get (), isa.c_str ());
456473 comgr_status != AMD_COMGR_STATUS_SUCCESS) {
457474 LogError (" Failed to set ISA name" );
@@ -540,13 +557,22 @@ hipError_t FatBinaryInfo::ExtractFatBinaryUsingCOMGR(const std::vector<hip::Devi
540557 auto elf_size = CodeObject::ElfSize (co);
541558 fatbin_dev_info_[device->deviceId ()] = new FatBinaryDeviceInfo (co, elf_size, 0 );
542559 fatbin_dev_info_[device->deviceId ()]->program_ = new amd::Program (*(device->asContext ()));
560+
543561 // Save the compiled code object
544562 compiled_co[target_id] = std::make_pair (co, elf_size);
563+ } else {
564+ // We found neither a compatible code object nor SPIRV
565+ LogPrintfError (
566+ " No compatible code objects found for: %s, value of HIP_FORCE_SPIRV_CODEOBJECT: %d" ,
567+ device->devices ()[0 ]->isa ().targetId (), HIP_FORCE_SPIRV_CODEOBJECT);
568+ hip_status = hipErrorInvalidValue;
569+ break ;
545570 }
546571 }
547572 } while (0 );
548573
549574 if (comgr_status != AMD_COMGR_STATUS_SUCCESS) {
575+ LogError (" comgr API call failed" );
550576 hip_status = hipErrorInvalidValue;
551577 }
552578
0 commit comments