diff options
author | David Phillips <david@sighup.nz> | 2017-02-22 17:12:10 +1300 |
---|---|---|
committer | David Phillips <david@sighup.nz> | 2017-02-22 17:12:10 +1300 |
commit | a872e835d72d657a6b1ce339177c15de3f23d31e (patch) | |
tree | fe631dae6465410027d4e030edacfa3589b26071 | |
parent | a5c06bbfa6326d080ab2d34cfef7fd3041cf58a7 (diff) | |
download | fractal-gen-opencl-a872e835d72d657a6b1ce339177c15de3f23d31e.tar.xz |
Expose platform selection to user
-rw-r--r-- | fractal-gen.c | 16 | ||||
-rw-r--r-- | trampoline.c | 109 | ||||
-rw-r--r-- | trampoline.h | 2 |
3 files changed, 114 insertions, 13 deletions
diff --git a/fractal-gen.c b/fractal-gen.c index 60b27e3..5f9e899 100644 --- a/fractal-gen.c +++ b/fractal-gen.c @@ -4,10 +4,10 @@ #include "trampoline.h" -int run(unsigned int size, unsigned int iterations) +int run(const char *preferred_platform, unsigned int size, unsigned int iterations) { fprintf(stderr, "Building CL trampoline... "); - if (tramp_init()) { + if (tramp_init(preferred_platform)) { fprintf(stderr, "Failed.\n"); return 1; } @@ -63,7 +63,7 @@ int run(unsigned int size, unsigned int iterations) void die_help() { - fprintf(stderr, "Syntax:\nfractal-gen [-s size] [-i max_iteratons]\n"); + fprintf(stderr, "Syntax:\nfractal-gen [-p platform] [-s size] [-i max_iteratons]\n"); exit(1); } @@ -71,9 +71,10 @@ int main(int argc, char **argv) { long size = 0; long iterations = 0; + char *preferred_platform = NULL; char c = '\0'; - while ((c = getopt(argc, argv, "s:i:")) != -1) { + while ((c = getopt(argc, argv, "s:i:p:")) != -1) { switch (c) { case 's': size = atoi(optarg); @@ -81,6 +82,9 @@ int main(int argc, char **argv) case 'i': iterations = atoi(optarg); break; + case 'p': + preferred_platform = optarg; + break; case '?': die_help(); return 1; /* mostly unreachable */ @@ -88,11 +92,11 @@ int main(int argc, char **argv) } } - if (size <= 0 || iterations <= 0) { + if (size <= 0 || iterations <= 0 || preferred_platform == NULL) { die_help(); return 1; /* mostly unreachable */ } - run(size, iterations); + run(preferred_platform, size, iterations); return 0; } diff --git a/trampoline.c b/trampoline.c index 9be250a..174ff26 100644 --- a/trampoline.c +++ b/trampoline.c @@ -20,16 +20,113 @@ static unsigned int size; static unsigned int iterations; +char *get_platform_info(cl_platform_id id, cl_platform_info value_name) +{ + cl_int ret = 0; + char *value = NULL; + size_t value_len = 0; + + ret = clGetPlatformInfo(id, value_name, 0, NULL, &value_len); + if (ret != CL_SUCCESS) { + fprintf(stderr, "Failed to get platform info for platform %d: %s\n", id, get_cl_error_string(ret)); + return NULL; + } + + value = malloc(value_len); + if (value == NULL) { + perror("value buffer malloc"); + return NULL; + } + + ret = clGetPlatformInfo(id, value_name, value_len, value, &value_len); + if (ret != CL_SUCCESS) { + fprintf(stderr, "Failed to get platform info for platform %d: %s\n", id, get_cl_error_string(ret)); + return NULL; + } + + return value; +} + +int select_platform(const char *preferred_platform) +{ + cl_uint i = 0; + cl_platform_id *platforms = NULL; + cl_uint platform_count = 0; + cl_int ret = 0; + int preferred_platform_found = 0; + char *p_name = NULL; + char *p_vendor = NULL; + char *p_version = NULL; + + ret = clGetPlatformIDs(0, NULL, &platform_count); + if (ret != CL_SUCCESS) { + fprintf(stderr, "Failed to get CL platform count: %s ", get_cl_error_string(ret)); + return 1; + } + + if (platform_count == 0) { + fprintf(stderr, "No OpenCL platforms available "); + return 1; + } + + platforms = calloc(platform_count, sizeof(cl_platform_id)); + if (platforms == NULL) { + perror("platform ID array calloc"); + return 1; + } + + ret = clGetPlatformIDs(platform_count, platforms, NULL); + if (ret != CL_SUCCESS) { + fprintf(stderr, "Failed to get CL platform IDs: %s ", get_cl_error_string(ret)); + return 1; + } + + fprintf(stderr, "\nAvailable platforms:\n"); + for (i = 0; i < platform_count; i++) { + p_name = get_platform_info(platforms[i], CL_PLATFORM_NAME); + p_vendor = get_platform_info(platforms[i], CL_PLATFORM_VENDOR); + p_version = get_platform_info(platforms[i], CL_PLATFORM_VERSION); + if ( p_name == NULL + || p_version == NULL + || p_vendor == NULL) { + free(p_name); + free(p_vendor); + free(p_version); + free(platforms); + return 1; + } + /* Is this platform the first preferred one? Select it for the lovely lady or gentleman */ + if (strcmp(preferred_platform, p_name) == 0 && !preferred_platform_found) { + platform = platforms[i]; + preferred_platform_found = 1; + } + fprintf(stderr, "\t* Platform \"%s\" - From %s (%s)%s\n", + p_name, p_vendor, p_version, platform == platforms[i] ? " [SELECTED]" : "" ); + + free(p_name); + free(p_vendor); + free(p_version); + } + + if (!preferred_platform_found) { + fprintf(stderr, "Warning: Preferred platform not found, falling back on first available platform.\n"); + platform = platforms[0]; + } + + + + return 0; +} + + /* FIXME print cl error messages with oclErrorString */ -int tramp_init() +int tramp_init(const char *preferred_platform) { cl_int ret; - /* FIXME expose platform selection to user and flarg the blopple */ -// ret = oclGetPlatformID(&platform); -// if (ret != CL_SUCCESS) -// return 1; - platform=0; + if (select_platform(preferred_platform)) { + return 1; + } /* FIXME expose device type to user */ ret = clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 0, NULL, &device_count); diff --git a/trampoline.h b/trampoline.h index fbcc453..35624a9 100644 --- a/trampoline.h +++ b/trampoline.h @@ -1,4 +1,4 @@ -int tramp_init(void); +int tramp_init(const char *preferred_platform); void tramp_destroy(void); int tramp_load_kernel(const char *filename); char *tramp_get_build_log(void); |