/* Plugin for offload execution on Intel MIC devices.

   Copyright (C) 2014-2016 Free Software Foundation, Inc.

   Contributed by Ilya Verbin <ilya.verbin@intel.com>.

   This file is part of the GNU Offloading and Multi Processing Library
   (libgomp).

   Libgomp is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.

   Under Section 7 of GPL version 3, you are granted additional
   permissions described in the GCC Runtime Library Exception, version
   3.1, as published by the Free Software Foundation.

   You should have received a copy of the GNU General Public License and
   a copy of the GCC Runtime Library Exception along with this program;
   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
   <http://www.gnu.org/licenses/>.  */

/* Host side part of a libgomp plugin.  */

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <utility>
#include <vector>
#include <map>
#include "libgomp-plugin.h"
#include "compiler_if_host.h"
#include "main_target_image.h"
#include "gomp-constants.h"

#define OFFLOAD_ACTIVE_WAIT_ENV	"OFFLOAD_ACTIVE_WAIT"

#ifdef DEBUG
#define TRACE(...)					    \
{							    \
fprintf (stderr, "HOST:\t%s:%s ", __FILE__, __FUNCTION__);  \
fprintf (stderr, __VA_ARGS__);				    \
fprintf (stderr, "\n");					    \
}
#else
#define TRACE { }
#endif


/* Start/end addresses of functions and global variables on a device.  */
typedef std::vector<addr_pair> AddrVect;

/* Addresses for one image and all devices.  */
typedef std::vector<AddrVect> DevAddrVect;

/* Addresses for all images and all devices.  */
typedef std::map<const void *, DevAddrVect> ImgDevAddrMap;

/* Image descriptor needed by __offload_[un]register_image.  */
struct TargetImageDesc {
  int64_t size;
  /* 10 characters is enough for max int value.  */
  char name[sizeof ("lib0000000000.so")];
  char data[];
};

/* Image descriptors, indexed by a pointer obtained from libgomp.  */
typedef std::map<const void *, TargetImageDesc *> ImgDescMap;


/* Total number of available devices.  */
static int num_devices;

/* Total number of shared libraries with offloading to Intel MIC.  */
static int num_images;

/* Two dimensional array: one key is a pointer to image,
   second key is number of device.  Contains a vector of pointer pairs.  */
static ImgDevAddrMap *address_table;

/* Descriptors of all images, registered in liboffloadmic.  */
static ImgDescMap *image_descriptors;

/* Thread-safe registration of the main image.  */
static pthread_once_t main_image_is_registered = PTHREAD_ONCE_INIT;

static VarDesc vd_host2tgt = {
  { 1, 1 },		      /* dst, src			      */
  { 1, 0 },		      /* in, out			      */
  1,			      /* alloc_if			      */
  1,			      /* free_if			      */
  4,			      /* align				      */
  0,			      /* mic_offset			      */
  { 0, 0, 0, 0, 0, 0, 0, 0 }, /* is_static, is_static_dstn, has_length,
				 is_stack_buf, sink_addr, alloc_disp,
				 is_noncont_src, is_noncont_dst	      */
  0,			      /* offset				      */
  0,			      /* size				      */
  1,			      /* count				      */
  0,			      /* alloc				      */
  0,			      /* into				      */
  0			      /* ptr				      */
};

static VarDesc vd_tgt2host = {
  { 1, 1 },		      /* dst, src			      */
  { 0, 1 },		      /* in, out			      */
  1,			      /* alloc_if			      */
  1,			      /* free_if			      */
  4,			      /* align				      */
  0,			      /* mic_offset			      */
  { 0, 0, 0, 0, 0, 0, 0, 0 }, /* is_static, is_static_dstn, has_length,
				 is_stack_buf, sink_addr, alloc_disp,
				 is_noncont_src, is_noncont_dst	      */
  0,			      /* offset				      */
  0,			      /* size				      */
  1,			      /* count				      */
  0,			      /* alloc				      */
  0,			      /* into				      */
  0			      /* ptr				      */
};


__attribute__((constructor))
static void
init (void)
{
  const char *active_wait = getenv (OFFLOAD_ACTIVE_WAIT_ENV);

  /* Disable active wait by default to avoid useless CPU usage.  */
  if (!active_wait)
    setenv (OFFLOAD_ACTIVE_WAIT_ENV, "0", 0);

  address_table = new ImgDevAddrMap;
  image_descriptors = new ImgDescMap;
  num_devices = _Offload_number_of_devices ();
}

extern "C" const char *
GOMP_OFFLOAD_get_name (void)
{
  const char *res = "intelmic";
  TRACE ("(): return %s", res);
  return res;
}

extern "C" unsigned int
GOMP_OFFLOAD_get_caps (void)
{
  unsigned int res = GOMP_OFFLOAD_CAP_OPENMP_400;
  TRACE ("(): return %x", res);
  return res;
}

extern "C" int
GOMP_OFFLOAD_get_type (void)
{
  enum offload_target_type res = OFFLOAD_TARGET_TYPE_INTEL_MIC;
  TRACE ("(): return %d", res);
  return res;
}

extern "C" int
GOMP_OFFLOAD_get_num_devices (unsigned int omp_requires_mask)
{
  /* Return -1 if no omp_requires_mask cannot be fulfilled but
     devices were present.  */
  if (num_devices > 0 && omp_requires_mask != 0)
    return -1;
  TRACE ("(): return %d", num_devices);
  return num_devices;
}

static bool
offload (const char *file, uint64_t line, int device, const char *name,
	 int num_vars, VarDesc *vars, const void **async_data)
{
  OFFLOAD ofld = __offload_target_acquire1 (&device, file, line);
  if (ofld)
    {
      if (async_data == NULL)
	return __offload_offload1 (ofld, name, 0, num_vars, vars, NULL, 0,
				   NULL, NULL);
      else
	{
	  OffloadFlags flags;
	  flags.flags = 0;
	  flags.bits.omp_async = 1;
	  return __offload_offload3 (ofld, name, 0, num_vars, vars, NULL, 0,
				     NULL, async_data, 0, NULL, flags, NULL);
	}
    }
  else
    {
      GOMP_PLUGIN_error ("%s:%d: Offload target acquire failed\n", file, line);
      return false;
    }
}

static void
register_main_image ()
{
  /* Do not check the return value, because old versions of liboffloadmic did
     not have return values.  */
  __offload_register_image (&main_target_image);

  /* liboffloadmic will call GOMP_PLUGIN_target_task_completion when
     asynchronous task on target is completed.  */
  __offload_register_task_callback (GOMP_PLUGIN_target_task_completion);
}

/* liboffloadmic loads and runs offload_target_main on all available devices
   during a first call to offload ().  */
extern "C" bool
GOMP_OFFLOAD_init_device (int device)
{
  TRACE ("(device = %d)", device);
  pthread_once (&main_image_is_registered, register_main_image);
  return offload (__FILE__, __LINE__, device, "__offload_target_init_proc", 0,
		  NULL, NULL);
}

extern "C" bool
GOMP_OFFLOAD_fini_device (int device)
{
  TRACE ("(device = %d)", device);

  /* liboffloadmic will finalize target processes on all available devices.  */
  __offload_unregister_image (&main_target_image);
  return true;
}

static bool
get_target_table (int device, int &num_funcs, int &num_vars, void **&table)
{
  VarDesc vd1[2] = { vd_tgt2host, vd_tgt2host };
  vd1[0].ptr = &num_funcs;
  vd1[0].size = sizeof (num_funcs);
  vd1[1].ptr = &num_vars;
  vd1[1].size = sizeof (num_vars);

  if (!offload (__FILE__, __LINE__, device, "__offload_target_table_p1", 2,
		vd1, NULL))
    return false;

  int table_size = num_funcs + 2 * num_vars;
  if (table_size > 0)
    {
      table = new void * [table_size];

      VarDesc vd2;
      vd2 = vd_tgt2host;
      vd2.ptr = table;
      vd2.size = table_size * sizeof (void *);

      return offload (__FILE__, __LINE__, device, "__offload_target_table_p2",
		      1, &vd2, NULL);
    }
  return true;
}

/* Offload TARGET_IMAGE to all available devices and fill address_table with
   corresponding target addresses.  */

static bool
offload_image (const void *target_image)
{
  void *image_start = ((void **) target_image)[0];
  void *image_end   = ((void **) target_image)[1];

  TRACE ("(target_image = %p { %p, %p })",
	 target_image, image_start, image_end);

  int64_t image_size = (uintptr_t) image_end - (uintptr_t) image_start;
  TargetImageDesc *image = (TargetImageDesc *) malloc (offsetof (TargetImageDesc, data)
						       + image_size);
  if (!image)
    {
      GOMP_PLUGIN_error ("%s: Can't allocate memory\n", __FILE__);
      return false;
    }

  image->size = image_size;
  sprintf (image->name, "lib%010d.so", num_images++);
  memcpy (image->data, image_start, image->size);

  TRACE ("() __offload_register_image %s { %p, %d }",
	 image->name, image_start, image->size);
  /* Do not check the return value, because old versions of liboffloadmic did
     not have return values.  */
  __offload_register_image (image);

  /* Receive tables for target_image from all devices.  */
  DevAddrVect dev_table;
  bool ret = true;
  for (int dev = 0; dev < num_devices; dev++)
    {
      int num_funcs = 0;
      int num_vars = 0;
      void **table = NULL;

      ret &= get_target_table (dev, num_funcs, num_vars, table);

      AddrVect curr_dev_table;

      for (int i = 0; i < num_funcs; i++)
	{
	  addr_pair tgt_addr;
	  tgt_addr.start = (uintptr_t) table[i];
	  tgt_addr.end = tgt_addr.start + 1;
	  TRACE ("() func %d:\t0x%llx..0x%llx", i,
		 tgt_addr.start, tgt_addr.end);
	  curr_dev_table.push_back (tgt_addr);
	}

      for (int i = 0; i < num_vars; i++)
	{
	  addr_pair tgt_addr;
	  tgt_addr.start = (uintptr_t) table[num_funcs+i*2];
	  tgt_addr.end = tgt_addr.start + (uintptr_t) table[num_funcs+i*2+1];
	  TRACE ("() var %d:\t0x%llx..0x%llx", i, tgt_addr.start, tgt_addr.end);
	  curr_dev_table.push_back (tgt_addr);
	}

      dev_table.push_back (curr_dev_table);
      delete [] table;
    }

  address_table->insert (std::make_pair (target_image, dev_table));
  image_descriptors->insert (std::make_pair (target_image, image));
  return ret;
}

/* Return the libgomp version number we're compatible with.  There is
   no requirement for cross-version compatibility.  */

extern "C" unsigned
GOMP_OFFLOAD_version (void)
{
  return GOMP_VERSION;
}

extern "C" int
GOMP_OFFLOAD_load_image (int device, const unsigned version,
			 const void *target_image, addr_pair **result)
{
  TRACE ("(device = %d, target_image = %p)", device, target_image);

  if (GOMP_VERSION_DEV (version) > GOMP_VERSION_INTEL_MIC)
    {
      GOMP_PLUGIN_error ("Offload data incompatible with intelmic plugin"
			 " (expected %u, received %u)",
			 GOMP_VERSION_INTEL_MIC, GOMP_VERSION_DEV (version));
      return -1;
    }

  /* If target_image is already present in address_table, then there is no need
     to offload it.  */
  if (address_table->count (target_image) == 0)
    {
      /* If fail, return -1 as error code.  */
      if (!offload_image (target_image))
	return -1;
    }

  AddrVect *curr_dev_table = &(*address_table)[target_image][device];
  int table_size = curr_dev_table->size ();
  addr_pair *table = (addr_pair *) malloc (table_size * sizeof (addr_pair));
  if (table == NULL)
    {
      GOMP_PLUGIN_error ("%s: Can't allocate memory\n", __FILE__);
      return -1;
    }

  std::copy (curr_dev_table->begin (), curr_dev_table->end (), table);
  *result = table;
  return table_size;
}

extern "C" bool
GOMP_OFFLOAD_unload_image (int device, unsigned version,
			   const void *target_image)
{
  if (GOMP_VERSION_DEV (version) > GOMP_VERSION_INTEL_MIC)
    {
      GOMP_PLUGIN_error ("Offload data incompatible with intelmic plugin"
			 " (expected %u, received %u)",
			 GOMP_VERSION_INTEL_MIC, GOMP_VERSION_DEV (version));
      return false;
    }

  TRACE ("(device = %d, target_image = %p)", device, target_image);

  /* liboffloadmic unloads the image from all available devices.  */
  if (image_descriptors->count (target_image) > 0)
    {
      TargetImageDesc *image_desc = (*image_descriptors)[target_image];
      __offload_unregister_image (image_desc);
      free (image_desc);

      address_table->erase (target_image);
      image_descriptors->erase (target_image);
    }
  return true;
}

extern "C" void *
GOMP_OFFLOAD_alloc (int device, size_t size)
{
  TRACE ("(device = %d, size = %d)", device, size);

  void *tgt_ptr;
  VarDesc vd[2] = { vd_host2tgt, vd_tgt2host };
  vd[0].ptr = &size;
  vd[0].size = sizeof (size);
  vd[1].ptr = &tgt_ptr;
  vd[1].size = sizeof (void *);

  if (!offload (__FILE__, __LINE__, device, "__offload_target_alloc", 2,
		vd, NULL))
    return NULL;

  return tgt_ptr;
}

extern "C" bool
GOMP_OFFLOAD_free (int device, void *tgt_ptr)
{
  TRACE ("(device = %d, tgt_ptr = %p)", device, tgt_ptr);

  VarDesc vd = vd_host2tgt;
  vd.ptr = &tgt_ptr;
  vd.size = sizeof (void *);

  return offload (__FILE__, __LINE__, device, "__offload_target_free", 1,
		  &vd, NULL);
}

extern "C" bool
GOMP_OFFLOAD_host2dev (int device, void *tgt_ptr, const void *host_ptr,
		       size_t size)
{
  TRACE ("(device = %d, tgt_ptr = %p, host_ptr = %p, size = %d)",
	 device, tgt_ptr, host_ptr, size);
  if (!size)
    return true;

  VarDesc vd1[2] = { vd_host2tgt, vd_host2tgt };
  vd1[0].ptr = &tgt_ptr;
  vd1[0].size = sizeof (void *);
  vd1[1].ptr = &size;
  vd1[1].size = sizeof (size);

  if (!offload (__FILE__, __LINE__, device, "__offload_target_host2tgt_p1", 2,
		vd1, NULL))
    return false;

  VarDesc vd2 = vd_host2tgt;
  vd2.ptr = (void *) host_ptr;
  vd2.size = size;

  return offload (__FILE__, __LINE__, device, "__offload_target_host2tgt_p2", 1,
		  &vd2, NULL);
}

extern "C" bool
GOMP_OFFLOAD_dev2host (int device, void *host_ptr, const void *tgt_ptr,
		       size_t size)
{
  TRACE ("(device = %d, host_ptr = %p, tgt_ptr = %p, size = %d)",
	 device, host_ptr, tgt_ptr, size);
  if (!size)
    return true;

  VarDesc vd1[2] = { vd_host2tgt, vd_host2tgt };
  vd1[0].ptr = &tgt_ptr;
  vd1[0].size = sizeof (void *);
  vd1[1].ptr = &size;
  vd1[1].size = sizeof (size);

  if (!offload (__FILE__, __LINE__, device, "__offload_target_tgt2host_p1", 2,
		vd1, NULL))
    return false;

  VarDesc vd2 = vd_tgt2host;
  vd2.ptr = (void *) host_ptr;
  vd2.size = size;

  return offload (__FILE__, __LINE__, device, "__offload_target_tgt2host_p2", 1,
		  &vd2, NULL);
}

extern "C" bool
GOMP_OFFLOAD_dev2dev (int device, void *dst_ptr, const void *src_ptr,
		      size_t size)
{
  TRACE ("(device = %d, dst_ptr = %p, src_ptr = %p, size = %d)",
	 device, dst_ptr, src_ptr, size);
  if (!size)
    return true;

  VarDesc vd[3] = { vd_host2tgt, vd_host2tgt, vd_host2tgt };
  vd[0].ptr = &dst_ptr;
  vd[0].size = sizeof (void *);
  vd[1].ptr = &src_ptr;
  vd[1].size = sizeof (void *);
  vd[2].ptr = &size;
  vd[2].size = sizeof (size);

  return offload (__FILE__, __LINE__, device, "__offload_target_tgt2tgt", 3,
		  vd, NULL);
}

extern "C" void
GOMP_OFFLOAD_async_run (int device, void *tgt_fn, void *tgt_vars,
			void **, void *async_data)
{
  TRACE ("(device = %d, tgt_fn = %p, tgt_vars = %p, async_data = %p)", device,
	 tgt_fn, tgt_vars, async_data);

  VarDesc vd[2] = { vd_host2tgt, vd_host2tgt };
  vd[0].ptr = &tgt_fn;
  vd[0].size = sizeof (void *);
  vd[1].ptr = &tgt_vars;
  vd[1].size = sizeof (void *);

  offload (__FILE__, __LINE__, device, "__offload_target_run", 2, vd,
	   (const void **) async_data);
}

extern "C" void
GOMP_OFFLOAD_run (int device, void *tgt_fn, void *tgt_vars, void **)
{
  TRACE ("(device = %d, tgt_fn = %p, tgt_vars = %p)", device, tgt_fn, tgt_vars);

  GOMP_OFFLOAD_async_run (device, tgt_fn, tgt_vars, NULL, NULL);
}
