This patch is part of the following series (all unreviewed so far)
but can be independently applied:

* [Patch] [gcn] Fix gfx906's sramecc setting,
  https://gcc.gnu.org/pipermail/gcc-patches/2025-February/675251.html

* "[gcn] Add gfx9-generic and generic-associated gfx*"
  (email subject: "Re: [Patch] [GCN] Handle generic ISA names in libgomp's 
plugin-gcn.c";
   this thread), 
https://gcc.gnu.org/pipermail/gcc-patches/2025-February/675259.html

* * *

This patch permits loading generic ISA code objects - by just
trying whether the runtime accepts it.  If not, it fails with
an error. - The error messages should be a bit more helpful in
some cases as before.


OK for mainline?


This becomes useful by configuring a gfx*-generic multilib,
once ROCR ("ROCm") support it; thus, this is a future proof
patch.

* * *

Note: This currently fails with all ROCm <= 6.3.2 as those
either don't recognize the generic ISA code or do not support
generic resolution. However, it looks as if one of the next
ROCm (AOMP?) releases will do.

Note 2: As the generic ISA is not yet supported, this patch does
not suggest compiling with -march=gfx*-generic, yet.

Note 3: The patch series is based on it (with some modifications):
https://gcc.gnu.org/pipermail/gcc-patches/2025-February/675200.html
that also has this -march= diagnostic.

Tobias
[GCN] Handle generic ISA names in libgomp's plugin-gcn.c

libgomp/ChangeLog:

	* plugin/plugin-gcn.c (ELFABIVERSION_AMDGPU_HSA_V6,
	EF_AMDGPU_GENERIC_VERSION_V, EF_AMDGPU_GENERIC_VERSION_OFFSET,
	GET_GENERIC_VERSION): New #define.
	(elf_gcn_isa_is_generic): New.
	(isa_matches_agent): Accept all generic code objects on the first
	go; extend the diagnostic and handle runtime-failed case.
	(create_and_finalize_hsa_program): Call it also after loading
	the code failed, pass the status.

 libgomp/plugin/plugin-gcn.c | 116 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 90 insertions(+), 26 deletions(-)

diff --git a/libgomp/plugin/plugin-gcn.c b/libgomp/plugin/plugin-gcn.c
index 8015a6f80f3..54d11478635 100644
--- a/libgomp/plugin/plugin-gcn.c
+++ b/libgomp/plugin/plugin-gcn.c
@@ -66,6 +66,14 @@
 #define R_AMDGPU_RELATIVE64	13	/* B + A  */
 #endif
 
+#define ELFABIVERSION_AMDGPU_HSA_V6		4
+
+#define EF_AMDGPU_GENERIC_VERSION_V		0xff000000  /* Mask.  */
+#define EF_AMDGPU_GENERIC_VERSION_OFFSET	24
+
+#define GET_GENERIC_VERSION(VAR) ((VAR & EF_AMDGPU_GENERIC_VERSION_V) \
+				  >> EF_AMDGPU_GENERIC_VERSION_OFFSET)
+
 /* GCN specific definitions for asynchronous queues.  */
 
 #define ASYNC_QUEUE_SIZE 64
@@ -242,7 +250,7 @@ struct kernel_dispatch
 };
 
 /* Structure of the kernargs segment, supporting console output.
- 
+
    This needs to match the definitions in Newlib, and the expectations
    in libgomp target code.  */
 
@@ -1668,6 +1676,13 @@ elf_gcn_isa_field (Elf64_Ehdr *image)
   return image->e_flags & EF_AMDGPU_MACH_MASK;
 }
 
+static int
+elf_gcn_isa_is_generic (Elf64_Ehdr *image)
+{
+  return (image->e_ident[8] == ELFABIVERSION_AMDGPU_HSA_V6
+	  && GET_GENERIC_VERSION (image->e_flags));
+}
+
 /* Returns the name that the HSA runtime uses for the ISA or NULL if we do not
    support the ISA. */
 
@@ -2399,38 +2414,87 @@ init_basic_kernel_info (struct kernel_info *kernel,
   return true;
 }
 
-/* Check that the GCN ISA of the given image matches the ISA of the agent. */
+/* If status is SUCCESS, assume that the code runs if either the ISA of agent
+   and code is the same - or it is generic code.
+   Otherwise, execution failed with the provided status code; try to give
+   some useful diagnostic.  */
 
 static bool
-isa_matches_agent (struct agent_info *agent, Elf64_Ehdr *image)
+isa_matches_agent (struct agent_info *agent, Elf64_Ehdr *image,
+		   hsa_status_t status)
 {
+  /* Generic image - assume that it works and only return to here
+     when it fails, i.e. fatal == true.  */
+  if (status == HSA_STATUS_SUCCESS && elf_gcn_isa_is_generic (image))
+    return true;
+
   int isa_field = elf_gcn_isa_field (image);
-  const char* isa_s = isa_name (isa_field);
-  if (!isa_s)
+  if (status == HSA_STATUS_SUCCESS && isa_field == agent->device_isa)
+    return true;
+
+  /* Either nongeneric and mismatch of the ISA - or generic but
+     not handled by the ROCm (e.g. because it is too old).  */
+
+  char msg[340];
+  char agent_isa_xs[8];
+  char device_isa_xs[8];
+  const char *agent_isa_s = isa_name (agent->device_isa);
+  const char *device_isa_s = isa_name (isa_field);
+  if (agent_isa_s == NULL)
     {
-      hsa_error ("Unsupported ISA in GCN code object.", HSA_STATUS_ERROR);
-      return false;
+      snprintf (agent_isa_xs, sizeof agent_isa_xs,
+		"0x%X", agent->device_isa);
+      agent_isa_s = agent_isa_xs;
     }
-
-  if (isa_field != agent->device_isa)
+  if (device_isa_s == NULL)
     {
-      char msg[204];
-      const char *agent_isa_s = isa_name (agent->device_isa);
-      assert (agent_isa_s);
-
-      snprintf (msg, sizeof msg,
-		"GCN code object ISA '%s' does not match GPU ISA '%s' "
-		"(device %d).\n"
-		"Try to recompile with '-foffload-options=-march=%s',\n"
-		"or use ROCR_VISIBLE_DEVICES to disable incompatible "
-		"devices.\n",
-		isa_s, agent_isa_s, agent->device_id, agent_isa_s);
-
-      hsa_error (msg, HSA_STATUS_ERROR);
-      return false;
+      snprintf (device_isa_xs, sizeof device_isa_xs, "0x%X", isa_field);
+      device_isa_s = device_isa_xs;
     }
 
-  return true;
+  /* Some error which should be unrelated to the ISA.  */
+  if (status != HSA_STATUS_SUCCESS
+      && status != HSA_STATUS_ERROR_INVALID_CODE_OBJECT
+      && status != HSA_STATUS_ERROR_INVALID_ISA_NAME
+      && status != HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS)
+    snprintf (msg, sizeof msg,
+	      "Could not load GCN code object with ISA %s on GPU with "
+	      "ISA %s (device %d).\n"
+	      "Consider using ROCR_VISIBLE_DEVICES to disable incompatible "
+	      "devices or run with LOADER_ENABLE_LOGGING=1 for more details",
+	      device_isa_s, agent_isa_s, agent->device_id);
+  else if (status == HSA_STATUS_ERROR_INVALID_ISA_NAME
+	   && elf_gcn_isa_is_generic (image))
+    snprintf (msg, sizeof msg,
+	      "Unsupported generic ISA %s on GPU with ISA %s (device %d).\n"
+	      "%s%s%s"
+	      "Consider using ROCR_VISIBLE_DEVICES to disable incompatible "
+	      "devices, run with LOADER_ENABLE_LOGGING=1 for more details, "
+	      "or try updating to a ROCm that supports this generic ISA",
+	      device_isa_s, agent_isa_s, agent->device_id,
+	      agent_isa_s[0] != '0'
+	      ? "Try to recompile with '-foffload-options=-march=" : "",
+	      agent_isa_s[0] != '0' ? agent_isa_s : "",
+	      agent_isa_s[0] != '0' ? ".\n" : "");
+  else if (agent_isa_s[0] == '0')
+    snprintf (msg, sizeof msg,
+	      "GCN code object ISA '%s' is incompatile to GPU ISA '%s' "
+	      "(device %d).\n"
+	      "Consider using ROCR_VISIBLE_DEVICES to disable incompatible "
+	      "devices or run with LOADER_ENABLE_LOGGING=1 for more details",
+	      device_isa_s, agent_isa_s, agent->device_id);
+  else
+    snprintf (msg, sizeof msg,
+	      "GCN code object ISA '%s' is incompatile to GPU ISA '%s' "
+	      "(device %d).\n"
+	      "Try to recompile with '-foffload-options=-march=%s',\n"
+	      "or use ROCR_VISIBLE_DEVICES to disable incompatible "
+	      "devices.\n",
+	      device_isa_s, agent_isa_s, agent->device_id, agent_isa_s);
+
+  hsa_error (msg, status != HSA_STATUS_SUCCESS
+		  ? status : HSA_STATUS_ERROR_INVALID_CODE_OBJECT);
+  return false;
 }
 
 /* Create and finalize the program consisting of all loaded modules.  */
@@ -2464,7 +2528,7 @@ create_and_finalize_hsa_program (struct agent_info *agent)
     {
       Elf64_Ehdr *image = (Elf64_Ehdr *)module->image_desc->gcn_image->image;
 
-      if (!isa_matches_agent (agent, image))
+      if (!isa_matches_agent (agent, image, HSA_STATUS_SUCCESS))
 	goto fail;
 
       hsa_code_object_t co = { 0 };
@@ -2482,7 +2546,7 @@ create_and_finalize_hsa_program (struct agent_info *agent)
 	(agent->executable, agent->id, co, "");
       if (status != HSA_STATUS_SUCCESS)
 	{
-	  hsa_error ("Could not load GCN code object", status);
+	  isa_matches_agent (agent, image, status);
 	  goto fail;
 	}
 

Reply via email to