+
+2020-01-29 Frederik Harwath <frederik@codesourcery.com>
+
+ * plugin-gcn.c (struct agent_info): Add fields "name" and
+ "vendor_name" ...
+ (GOMP_OFFLOAD_init_device): ... and init from here.
+ (struct hsa_context_info): Add field "driver_version_s" ...
+ (init_hsa_contest): ... and init from here.
+ (GOMP_OFFLOAD_openacc_get_property): Replace stub with a proper
+ implementation.
+ * testsuite/libgomp.oacc-c-c++-common/acc_get_property.c:
+ Enable test execution for amdgcn and host offloading targets.
+ * testsuite/libgomp.oacc-fortran/acc_get_property.f90: Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/acc_get_property-aux.c
+ (expect_device_properties): Split function into ...
+ (expect_device_string_properties): ... this new function ...
+ (expect_device_memory): ... and this new function.
+ * testsuite/libgomp.oacc-c-c++-common/acc_get_property-gcn.c:
+ Add test.
+
2020-01-28 Julian Brown <julian@codesourcery.com>
* testsuite/libgomp.oacc-fortran/deep-copy-2.f90: Remove test from here.
/* The instruction set architecture of the device. */
gcn_isa device_isa;
-
+ /* Name of the agent. */
+ char name[64];
+ /* Name of the vendor of the agent. */
+ char vendor_name[64];
/* Command queues of the agent. */
hsa_queue_t *sync_queue;
struct goacc_asyncqueue *async_queues, *omp_async_queue;
int agent_count;
/* Array of agent_info structures describing the individual HSA agents. */
struct agent_info *agents;
+ /* Driver version string. */
+ char driver_version_s[30];
};
/* Format of the on-device heap.
GOMP_PLUGIN_error ("Failed to list all HSA runtime agents");
}
+ uint16_t minor, major;
+ status = hsa_fns.hsa_system_get_info_fn (HSA_SYSTEM_INFO_VERSION_MINOR,
+ &minor);
+ if (status != HSA_STATUS_SUCCESS)
+ GOMP_PLUGIN_error ("Failed to obtain HSA runtime minor version");
+ status = hsa_fns.hsa_system_get_info_fn (HSA_SYSTEM_INFO_VERSION_MAJOR,
+ &major);
+ if (status != HSA_STATUS_SUCCESS)
+ GOMP_PLUGIN_error ("Failed to obtain HSA runtime major version");
+
+ size_t len = sizeof hsa_context.driver_version_s;
+ int printed = snprintf (hsa_context.driver_version_s, len,
+ "HSA Runtime %hu.%hu", (unsigned short int)major,
+ (unsigned short int)minor);
+ if (printed >= len)
+ GCN_WARNING ("HSA runtime version string was truncated."
+ "Version %hu.%hu is too long.", (unsigned short int)major,
+ (unsigned short int)minor);
+
hsa_context.initialized = true;
return true;
}
return hsa_error ("Error requesting maximum queue size of the GCN agent",
status);
- char buf[64];
status = hsa_fns.hsa_agent_get_info_fn (agent->id, HSA_AGENT_INFO_NAME,
- &buf);
+ &agent->name);
if (status != HSA_STATUS_SUCCESS)
return hsa_error ("Error querying the name of the agent", status);
- agent->device_isa = isa_code (buf);
+ agent->device_isa = isa_code (agent->name);
if (agent->device_isa < 0)
- return hsa_error ("Unknown GCN agent architecture.", HSA_STATUS_ERROR);
+ return hsa_error ("Unknown GCN agent architecture", HSA_STATUS_ERROR);
+
+ status = hsa_fns.hsa_agent_get_info_fn (agent->id, HSA_AGENT_INFO_VENDOR_NAME,
+ &agent->vendor_name);
+ if (status != HSA_STATUS_SUCCESS)
+ return hsa_error ("Error querying the vendor name of the agent", status);
status = hsa_fns.hsa_queue_create_fn (agent->id, queue_size,
HSA_QUEUE_TYPE_MULTI,
union goacc_property_value
GOMP_OFFLOAD_openacc_get_property (int device, enum goacc_property prop)
{
- /* Stub. Check device and return default value for unsupported properties. */
- /* TODO: Implement this function. */
- get_agent_info (device);
+ struct agent_info *agent = get_agent_info (device);
+
+ union goacc_property_value propval = { .val = 0 };
+
+ switch (prop)
+ {
+ case GOACC_PROPERTY_FREE_MEMORY:
+ /* Not supported. */
+ break;
+ case GOACC_PROPERTY_MEMORY:
+ {
+ size_t size;
+ hsa_region_t region = agent->data_region;
+ hsa_status_t status =
+ hsa_fns.hsa_region_get_info_fn (region, HSA_REGION_INFO_SIZE, &size);
+ if (status == HSA_STATUS_SUCCESS)
+ propval.val = size;
+ break;
+ }
+ case GOACC_PROPERTY_NAME:
+ propval.ptr = agent->name;
+ break;
+ case GOACC_PROPERTY_VENDOR:
+ propval.ptr = agent->vendor_name;
+ break;
+ case GOACC_PROPERTY_DRIVER:
+ propval.ptr = hsa_context.driver_version_s;
+ break;
+ }
- union goacc_property_value nullval = { .val = 0 };
- return nullval;
+ return propval;
}
/* Set up plugin-specific thread-local-data (host-side). */
#include <stdio.h>
#include <string.h>
-void expect_device_properties
-(acc_device_t dev_type, int dev_num,
- size_t expected_memory, const char* expected_vendor,
- const char* expected_name, const char* expected_driver)
-{
- const char *vendor = acc_get_property_string (dev_num, dev_type,
- acc_property_vendor);
- if (strcmp (vendor, expected_vendor))
- {
- fprintf (stderr, "Expected acc_property_vendor to equal \"%s\", "
- "but was \"%s\".\n", expected_vendor, vendor);
- abort ();
- }
-
- size_t total_mem = acc_get_property (dev_num, dev_type,
- acc_property_memory);
- if (total_mem != expected_memory)
- {
- fprintf (stderr, "Expected acc_property_memory to equal %zu, "
- "but was %zu.\n", expected_memory, total_mem);
- abort ();
-
- }
- size_t free_mem = acc_get_property (dev_num, dev_type,
- acc_property_free_memory);
- if (free_mem > total_mem)
- {
- fprintf (stderr, "Expected acc_property_free_memory <= acc_property_memory"
- ", but free memory was %zu and total memory was %zu.\n",
- free_mem, total_mem);
- abort ();
- }
+void expect_device_string_properties (acc_device_t dev_type, int dev_num,
+ const char* expected_vendor,
+ const char* expected_name,
+ const char* expected_driver)
+{
+const char *vendor = acc_get_property_string (dev_num, dev_type,
+ acc_property_vendor);
+if (strcmp (vendor, expected_vendor))
+{
+ fprintf (stderr, "Expected acc_property_vendor to equal \"%s\", "
+ "but was \"%s\".\n", expected_vendor, vendor);
+ abort ();
+}
const char *name = acc_get_property_string (dev_num, dev_type,
acc_property_name);
"but was %s.\n", s);
abort ();
}
+}
+
+void expect_device_memory (acc_device_t dev_type, int dev_num,
+ size_t expected_total_memory)
+{
+
+ size_t total_mem = acc_get_property (dev_num, dev_type,
+ acc_property_memory);
+
+ if (total_mem != expected_total_memory)
+ {
+ fprintf (stderr, "Expected acc_property_memory to equal %zu, "
+ "but was %zu.\n", expected_total_memory, total_mem);
+ abort ();
+ }
+ size_t free_mem = acc_get_property (dev_num, dev_type,
+ acc_property_free_memory);
+ if (free_mem > total_mem)
+ {
+ fprintf (stderr, "Expected acc_property_free_memory <= acc_property_memory"
+ ", but free memory was %zu and total memory was %zu.\n",
+ free_mem, total_mem);
+ abort ();
+ }
+}
+void expect_device_properties (acc_device_t dev_type, int dev_num,
+ size_t expected_total_memory,
+ const char* expected_vendor,
+ const char* expected_name,
+ const char* expected_driver)
+{
+ expect_device_string_properties (dev_type, dev_num, expected_vendor,
+ expected_name, expected_driver);
+ expect_device_memory (dev_type, dev_num, expected_total_memory);
}
--- /dev/null
+/* Test the `acc_get_property' and `acc_get_property_string' library
+ functions on amdgcn devices by comparing property values with
+ those obtained through the HSA API. */
+/* { dg-additional-sources acc_get_property-aux.c } */
+/* { dg-additional-options "-ldl" } */
+/* { dg-do run { target openacc_amdgcn_accel_selected } } */
+
+#include <dlfcn.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openacc.h>
+
+#ifndef __cplusplus
+typedef int bool;
+#endif
+#include <hsa.h>
+
+
+void expect_device_string_properties (acc_device_t dev_type, int dev_num,
+ const char* expected_vendor,
+ const char* expected_name,
+ const char* expected_driver);
+
+hsa_status_t (*hsa_agent_get_info_fn) (hsa_agent_t agent,
+ hsa_agent_info_t attribute,
+ void *value);
+hsa_status_t (*hsa_system_get_info_fn) (hsa_system_info_t attribute,
+ void *value);
+hsa_status_t (*hsa_iterate_agents_fn)
+(hsa_status_t (*callback)(hsa_agent_t agent, void *data), void *data);
+hsa_status_t (*hsa_init_fn) (void);
+
+char* support_cpu_devices;
+
+void test_setup ()
+{
+ char* env_runtime;
+ char* hsa_runtime_lib;
+ void *handle;
+
+#define DLSYM_FN(function) \
+ function##_fn = (typeof(function##_fn))dlsym (handle, #function); \
+ if (function##_fn == NULL) \
+ { \
+ fprintf (stderr, "Could not get symbol " #function ".\n"); \
+ abort (); \
+ }
+
+ env_runtime = getenv ("HSA_RUNTIME_LIB");
+ hsa_runtime_lib = env_runtime ? env_runtime : (char*)"libhsa-runtime64.so";
+
+ handle = dlopen (hsa_runtime_lib, RTLD_LAZY);
+ if (!handle)
+ {
+ fprintf (stderr, "Could not load %s.\n", hsa_runtime_lib);
+ abort ();
+ }
+
+ DLSYM_FN (hsa_agent_get_info)
+ DLSYM_FN (hsa_system_get_info)
+ DLSYM_FN (hsa_iterate_agents)
+ DLSYM_FN (hsa_init)
+
+ hsa_init_fn ();
+
+ support_cpu_devices = getenv ("GCN_SUPPORT_CPU_DEVICES");
+}
+
+static hsa_status_t check_agent_properties (hsa_agent_t agent, void *dev_num_arg)
+{
+
+ char name[64];
+ char vendor_name[64];
+ uint16_t minor;
+ uint16_t major;
+ char driver[60];
+
+ hsa_status_t status;
+ hsa_device_type_t device_type;
+ int* dev_num = (int*)dev_num_arg;
+
+#define AGENT_GET_INFO(info_type, val) \
+ status = hsa_agent_get_info_fn (agent, info_type, &val); \
+ if (status != HSA_STATUS_SUCCESS) \
+ { \
+ fprintf (stderr, "Failed to obtain " #info_type ".\n"); \
+ abort (); \
+ }
+#define SYSTEM_GET_INFO(info_type, val) \
+ status = hsa_system_get_info_fn (info_type, &val); \
+ if (status != HSA_STATUS_SUCCESS) \
+ { \
+ fprintf (stderr, "Failed to obtain " #info_type ".\n"); \
+ abort (); \
+ }
+
+ AGENT_GET_INFO (HSA_AGENT_INFO_DEVICE, device_type)
+
+ /* Skip unsupported device types. Mimic the GCN plugin's behavior. */
+ if (!(device_type == HSA_DEVICE_TYPE_GPU
+ || (support_cpu_devices && device_type == HSA_DEVICE_TYPE_CPU)))
+ return HSA_STATUS_SUCCESS;
+
+ AGENT_GET_INFO (HSA_AGENT_INFO_NAME, name)
+ AGENT_GET_INFO (HSA_AGENT_INFO_VENDOR_NAME, vendor_name)
+
+ SYSTEM_GET_INFO (HSA_SYSTEM_INFO_VERSION_MINOR, minor)
+ SYSTEM_GET_INFO (HSA_SYSTEM_INFO_VERSION_MAJOR, major)
+
+ snprintf (driver, sizeof driver, "HSA Runtime %hu.%hu",
+ (unsigned short int)major, (unsigned short int)minor);
+
+ expect_device_string_properties(acc_device_radeon, *dev_num,
+ vendor_name, name, driver);
+
+ (*dev_num)++;
+
+ return status;
+}
+
+int main ()
+{
+ int dev_num = 0;
+ test_setup ();
+
+ hsa_status_t status =
+ hsa_iterate_agents_fn (&check_agent_properties, &dev_num);
+
+ return status;
+}
of all device types mentioned in the OpenACC standard.
See also acc_get_property.f90. */
-/* { dg-do run { target { { ! { openacc_host_selected } } && { ! { openacc_amdgcn_accel_selected } } } } } */
-/* FIXME: This test does not work with the GCN implementation stub yet. */
+/* { dg-do run } */
#include <openacc.h>
#include <stdlib.h>
const char *s;
size_t v;
- int dev_count = acc_get_num_devices(type);
+ int dev_count = acc_get_num_devices (type);
for (int i = 0; i < dev_count; ++i)
{
! of all device types mentioned in the OpenACC standard.
!
! See also acc_get_property.c
-! { dg-do run { target { { ! { openacc_host_selected } } && { ! { openacc_amdgcn_accel_selected } } } } }
-! FIXME: This test does not work with the GCN implementation stub yet.
program test
use openacc