Example #1
0
/* write content[count] into a temporary file, and return the tempfile name in
 * output_path */
int
pocl_write_tempfile (char *output_path, const char *prefix, const char *suffix,
                     const char *content, uint64_t count, int *ret_fd)
{
  assert (output_path);
  assert (prefix);
  assert (suffix);
  assert (content);
  assert (count > 0);

  int fd, err;

  err = pocl_mk_tempname (output_path, prefix, suffix, &fd);
  if (err)
    {
      POCL_MSG_ERR ("pocl_mk_tempname() failed\n");
      return err;
    }
  size_t bytes = (size_t)count;
  ssize_t res;
  do
    {
      res = write (fd, content, bytes);
      if (res < 0)
        {
          POCL_MSG_ERR ("write(%s) failed\n", output_path);
          return errno;
        }
      else
        {
          bytes -= res;
          content += res;
        }
    }
  while (bytes > 0);

#ifdef HAVE_FDATASYNC
  if (fdatasync (fd))
    {
      POCL_MSG_ERR ("fdatasync() failed\n");
      return errno;
    }
#elif defined(HAVE_FSYNC)
  if (fsync (fd))
    return errno;
#endif

  err = 0;
  if (ret_fd)
    *ret_fd = fd;
  else
    {
      err = close (fd);
    }

  return err ? errno : 0;
}
Example #2
0
int
pocl_mk_tempname (char *output, const char *prefix, const char *suffix,
                  int *ret_fd)
{
#if defined(_MSC_VER) || defined(__MINGW32__)
#error "making temporary files on Windows not implemented"
#elif defined(HAVE_MKOSTEMPS) || defined(HAVE_MKSTEMPS) || defined(__ANDROID__)
  /* using mkstemp() instead of tmpnam() has no real benefit
   * here, as we have to pass the filename to llvm,
   * but tmpnam() generates an annoying warning... */
  int fd;

  strncpy (output, prefix, POCL_FILENAME_LENGTH);
  size_t len = strlen (prefix);
  strncpy (output + len, "_XXXXXX", (POCL_FILENAME_LENGTH - len));

#ifdef __ANDROID__
  fd = pocl_mkstemp (output);
#else
  if (suffix)
    {
      len += 7;
      strncpy (output + len, suffix, (POCL_FILENAME_LENGTH - len));
#ifdef HAVE_MKOSTEMPS
      fd = mkostemps (output, strlen (suffix), O_CLOEXEC);
#else
      fd = mkstemps (output, strlen (suffix));
#endif
    }
  else
#ifdef HAVE_MKOSTEMPS
    fd = mkostemp (output, O_CLOEXEC);
#else
    fd = mkstemp (output);
#endif
#endif

  if (fd < 0)
    {
      POCL_MSG_ERR ("mkstemp() failed\n");
      return errno;
    }

  int err = 0;
  if (ret_fd)
    *ret_fd = fd;
  else
    {
      err = close (fd);
    }
  return err ? errno : 0;
#else
#error mkostemps() / mkstemps() both unavailable
#endif
}
cl_int
program_compile_dynamic_wg_binaries(cl_program program)
{
  unsigned i, device_i;
  cl_int errcode = CL_SUCCESS;
  _cl_command_node cmd;

  assert(program->num_kernels);
  assert(program->build_status == CL_BUILD_SUCCESS);

  memset(&cmd, 0, sizeof(_cl_command_node));
  cmd.type = CL_COMMAND_NDRANGE_KERNEL;
  char cachedir[POCL_FILENAME_LENGTH];
  cmd.command.run.tmp_dir = cachedir;
  POCL_LOCK_OBJ(program);

  /* build the dynamic WG sized parallel.bc and device specific code,
 * for each kernel & device combo */
  for (device_i = 0; device_i < program->num_devices; ++device_i)
    {
      cl_device_id device = program->devices[device_i];

      /* program may not be built for some of its devices */
      if (program->pocl_binaries[device_i] || (!program->binaries[device_i]))
        continue;

      cmd.device = device;

      for (i=0; i < program->num_kernels; i++)
        {
          pocl_cache_make_kernel_cachedir_path(cachedir, program, device,
                                               program->default_kernels[i],
                                               0,0,0);

          errcode = pocl_llvm_generate_workgroup_function(device,
                                                          program->default_kernels[i],
                                                          0,0,0);
          if (errcode != CL_SUCCESS)
            {
              POCL_MSG_ERR("Failed to generate workgroup function for "
                           "kernel %s for device %s\n",
                           program->kernel_names[i], device->short_name);
              goto RET;
            }
          cmd.command.run.kernel = program->default_kernels[i];
          device->ops->compile_kernel(&cmd, program->default_kernels[i],
                                      device);
        }

    }

RET:
  POCL_UNLOCK_OBJ(program);
  return errcode;
}
Example #4
0
int context_set_properties(cl_context                    context,
                           const cl_context_properties * properties,
                           cl_int *                      errcode)
{
  unsigned i;
  int num_properties = 0;
  
  context->properties = NULL;
  
  /* verify if data in properties is valid
   * and set them */
  if (properties)
    {
      const cl_context_properties *p = properties;
      const cl_context_properties *q;
      
      cl_platform_id platforms[1];
      cl_uint num_platforms;
      cl_bool platform_found;

      POname(clGetPlatformIDs)(1, platforms, &num_platforms);

      num_properties = 0;
      while (p[0] != 0)
        {
          /* redefinition of the same property */
          for(q=properties; q<p; q+=2)
            if (q[0] == p[0])
              {
                POCL_MSG_ERR("Duplicate properties: %lu\n", (unsigned long)q[0]);
                *errcode = CL_INVALID_PROPERTY; 
                return 0;
              }
          
          switch (p[0])
            {
            case CL_CONTEXT_PLATFORM:

              /* pocl just have one platform */
              platform_found = CL_FALSE;
              for (i=0; i<num_platforms; i++)
                if ((cl_platform_id)p[1] == platforms[i])
                  platform_found = CL_TRUE;

              if (platform_found == CL_FALSE)
                {
                  POCL_MSG_ERR("Could not find platform %p\n", (void*)p[1]);
                  *errcode = CL_INVALID_PLATFORM;
                  return 0;
                }

              p += 2;
              break;

            default: 
              POCL_MSG_ERR("Unknown context property: %lu\n", (unsigned long)p[0]);
              *errcode = CL_INVALID_PROPERTY;
              return 0;
            }
          num_properties++;
        }

      context->properties = (cl_context_properties *) malloc
        ((num_properties * 2 + 1) * sizeof(cl_context_properties));
      if (context->properties == NULL)
        {
          *errcode = CL_OUT_OF_HOST_MEMORY;
          return 0;
        }
      
      memcpy(context->properties, properties, 
             (num_properties * 2 + 1) * sizeof(cl_context_properties));
      context->num_properties = num_properties;

      *errcode = 0;
      return num_properties;
    }
  else
    {
      context->properties     = NULL;
      context->num_properties = 0;
      
      *errcode = 0;
      return 0;
    }
}
Example #5
0
int 
pocl_write_file(const char *path, const char* content,
                uint64_t    count,
                int         append,
                int         dont_rewrite) 
{
  assert(path);
  assert(content);
  
  if (pocl_exists(path)) 
    {
      if (dont_rewrite) 
        {
          if (!append)
            return 0;
        } 
      else 
        {
          int res = pocl_remove(path);
          if (res)
            {
              POCL_MSG_ERR ("pocl_remove(%s) failed\n", path);
              return res;
            }
        }
    }
  
  FILE *f;
  if (append)
    f = fopen(path, "a");
  else
    f = fopen(path, "w");

  if (f == NULL)
    {
      POCL_MSG_ERR ("fopen(%s) failed\n", path);
      return -1;
    }

  if (fwrite (content, 1, (size_t)count, f) < (size_t)count)
    {
      POCL_MSG_ERR ("fwrite(%s) failed\n", path);
      return -1;
    }

  if (fflush (f))
    {
      POCL_MSG_ERR ("fflush() failed\n");
      return errno;
    }

#ifdef HAVE_FDATASYNC
  if (fdatasync (fileno (f)))
    {
      POCL_MSG_ERR ("fdatasync() failed\n");
      return errno;
    }
#elif defined(HAVE_FSYNC)
  if (fsync (fileno (f)))
    {
      POCL_MSG_ERR ("fsync() failed\n");
      return errno;
    }
#endif

  return fclose(f);
}
Example #6
0
int
pocl_topology_detect_device_info(cl_device_id device)
{
  hwloc_topology_t pocl_topology;
  int ret = 0;

#ifdef HWLOC_API_2
  if (hwloc_get_api_version () < 0x20000)
    POCL_MSG_ERR ("pocl was compiled against libhwloc 2.x but is"
                  "actually running against libhwloc 1.x \n");
#else
  if (hwloc_get_api_version () >= 0x20000)
    POCL_MSG_ERR ("pocl was compiled against libhwloc 1.x but is"
                  "actually running against libhwloc 2.x \n");
#endif

  /*

   * hwloc's OpenCL backend causes problems at the initialization stage
   * because it reloads libpocl.so via the ICD loader.
   *
   * See: https://github.com/pocl/pocl/issues/261
   *
   * The only trick to stop hwloc from initializing the OpenCL plugin
   * I could find is to point the plugin search path to a place where there
   * are no plugins to be found.
   */
  setenv ("HWLOC_PLUGINS_PATH", "/dev/null", 1);

  ret = hwloc_topology_init (&pocl_topology);
  if (ret == -1)
  {
    POCL_MSG_ERR ("Cannot initialize the topology.\n");
    return ret;
  }

#ifdef HWLOC_API_2
  hwloc_topology_set_io_types_filter(pocl_topology, HWLOC_TYPE_FILTER_KEEP_NONE);
  hwloc_topology_set_type_filter (pocl_topology, HWLOC_OBJ_SYSTEM, HWLOC_TYPE_FILTER_KEEP_NONE);
  hwloc_topology_set_type_filter (pocl_topology, HWLOC_OBJ_GROUP, HWLOC_TYPE_FILTER_KEEP_NONE);
  hwloc_topology_set_type_filter (pocl_topology, HWLOC_OBJ_BRIDGE, HWLOC_TYPE_FILTER_KEEP_NONE);
  hwloc_topology_set_type_filter (pocl_topology, HWLOC_OBJ_MISC, HWLOC_TYPE_FILTER_KEEP_NONE);
  hwloc_topology_set_type_filter (pocl_topology, HWLOC_OBJ_PCI_DEVICE, HWLOC_TYPE_FILTER_KEEP_NONE);
  hwloc_topology_set_type_filter (pocl_topology, HWLOC_OBJ_OS_DEVICE, HWLOC_TYPE_FILTER_KEEP_NONE);
#else
  hwloc_topology_ignore_type (pocl_topology, HWLOC_TOPOLOGY_FLAG_WHOLE_IO);
  hwloc_topology_ignore_type (pocl_topology, HWLOC_OBJ_SYSTEM);
  hwloc_topology_ignore_type (pocl_topology, HWLOC_OBJ_GROUP);
  hwloc_topology_ignore_type (pocl_topology, HWLOC_OBJ_BRIDGE);
  hwloc_topology_ignore_type (pocl_topology, HWLOC_OBJ_MISC);
  hwloc_topology_ignore_type (pocl_topology, HWLOC_OBJ_PCI_DEVICE);
  hwloc_topology_ignore_type (pocl_topology, HWLOC_OBJ_OS_DEVICE);
#endif

  ret = hwloc_topology_load (pocl_topology);
  if (ret == -1)
  {
    POCL_MSG_ERR ("Cannot load the topology.\n");
    goto exit_destroy;
  }

#ifdef HWLOC_API_2
  device->global_mem_size =
      hwloc_get_root_obj(pocl_topology)->total_memory;
#else
  device->global_mem_size =
      hwloc_get_root_obj(pocl_topology)->memory.total_memory;
#endif

  // Try to get the number of CPU cores from topology
  int depth = hwloc_get_type_depth(pocl_topology, HWLOC_OBJ_PU);
  if(depth != HWLOC_TYPE_DEPTH_UNKNOWN)
    device->max_compute_units = hwloc_get_nbobjs_by_depth(pocl_topology, depth);

  /* Find information about global memory cache by looking at the first
   * cache covering the first PU */
  do {
      size_t cache_size = 0, cacheline_size = 0;

      hwloc_obj_t core
          = hwloc_get_next_obj_by_type (pocl_topology, HWLOC_OBJ_CORE, NULL);
      if (core)
        {
          hwloc_obj_t cache
              = hwloc_get_shared_cache_covering_obj (pocl_topology, core);
          if ((cache) && (cache->attr))
            {
              cacheline_size = cache->attr->cache.linesize;
              cache_size = cache->attr->cache.size;
            }
          else
            core = NULL; /* fallback to L1 cache size */
        }

      hwloc_obj_t pu
          = hwloc_get_next_obj_by_type (pocl_topology, HWLOC_OBJ_PU, NULL);
      if (!core && pu)
        {
          hwloc_obj_t cache
              = hwloc_get_shared_cache_covering_obj (pocl_topology, pu);
          if ((cache) && (cache->attr))
            {
              cacheline_size = cache->attr->cache.linesize;
              cache_size = cache->attr->cache.size;
            }
        }

      if (!cache_size || !cacheline_size)
        break;

      device->global_mem_cache_type
          = 0x2; // CL_READ_WRITE_CACHE, without including all of CL/cl.h
      device->global_mem_cacheline_size = cacheline_size;
      device->global_mem_cache_size = cache_size;
  } while (0);

  // Destroy topology object and return
exit_destroy:
  hwloc_topology_destroy (pocl_topology);
  return ret;

}