Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@@ -0,0 +1,344 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
#include "cean_util.h"
#include "offload_common.h"
// 1. allocate element of CeanReadRanges type
// 2. initialized it for reading consequently contiguous ranges
// described by "ap" argument
CeanReadRanges * init_read_ranges_arr_desc(const arr_desc *ap)
{
CeanReadRanges * res;
// find the max contiguous range
int64_t rank = ap->rank - 1;
int64_t length = ap->dim[rank].size;
for (; rank >= 0; rank--) {
if (ap->dim[rank].stride == 1) {
length *= (ap->dim[rank].upper - ap->dim[rank].lower + 1);
if (rank > 0 && length != ap->dim[rank - 1].size) {
break;
}
}
else {
break;
}
}
res =(CeanReadRanges *)malloc(sizeof(CeanReadRanges) +
(ap->rank - rank) * sizeof(CeanReadDim));
res->current_number = 0;
res->range_size = length;
res->last_noncont_ind = rank;
// calculate number of contiguous ranges inside noncontiguous dimensions
int count = 1;
bool prev_is_cont = true;
int64_t offset = 0;
for (; rank >= 0; rank--) {
res->Dim[rank].count = count;
res->Dim[rank].size = ap->dim[rank].stride * ap->dim[rank].size;
count *= (prev_is_cont && ap->dim[rank].stride == 1? 1 :
(ap->dim[rank].upper - ap->dim[rank].lower +
ap->dim[rank].stride) / ap->dim[rank].stride);
prev_is_cont = false;
offset +=(ap->dim[rank].lower - ap->dim[rank].lindex) *
ap->dim[rank].size;
}
res->range_max_number = count;
res -> ptr = (void*)ap->base;
res -> init_offset = offset;
return res;
}
// check if ranges described by 1 argument could be transferred into ranges
// described by 2-nd one
bool cean_ranges_match(
CeanReadRanges * read_rng1,
CeanReadRanges * read_rng2
)
{
return ( read_rng1 == NULL || read_rng2 == NULL ||
(read_rng1->range_size % read_rng2->range_size == 0 ||
read_rng2->range_size % read_rng1->range_size == 0));
}
// Set next offset and length and returns true for next range.
// Returns false if the ranges are over.
bool get_next_range(
CeanReadRanges * read_rng,
int64_t *offset
)
{
if (++read_rng->current_number > read_rng->range_max_number) {
read_rng->current_number = 0;
return false;
}
int rank = 0;
int num = read_rng->current_number - 1;
int64_t cur_offset = 0;
int num_loc;
for (; rank <= read_rng->last_noncont_ind; rank++) {
num_loc = num / read_rng->Dim[rank].count;
cur_offset += num_loc * read_rng->Dim[rank].size;
num = num % read_rng->Dim[rank].count;
}
*offset = cur_offset + read_rng->init_offset;
return true;
}
bool is_arr_desc_contiguous(const arr_desc *ap)
{
int64_t rank = ap->rank - 1;
int64_t length = ap->dim[rank].size;
for (; rank >= 0; rank--) {
if (ap->dim[rank].stride > 1 &&
ap->dim[rank].upper - ap->dim[rank].lower != 0) {
return false;
}
else if (length != ap->dim[rank].size) {
for (; rank >= 0; rank--) {
if (ap->dim[rank].upper - ap->dim[rank].lower != 0) {
return false;
}
}
return true;
}
length *= (ap->dim[rank].upper - ap->dim[rank].lower + 1);
}
return true;
}
int64_t cean_get_transf_size(CeanReadRanges * read_rng)
{
return(read_rng->range_max_number * read_rng->range_size);
}
static uint64_t last_left, last_right;
typedef void (*fpp)(const char *spaces, uint64_t low, uint64_t high, int esize);
static void generate_one_range(
const char *spaces,
uint64_t lrange,
uint64_t rrange,
fpp fp,
int esize
)
{
OFFLOAD_TRACE(3,
"%s generate_one_range(lrange=%p, rrange=%p, esize=%d)\n",
spaces, (void*)lrange, (void*)rrange, esize);
if (last_left == -1) {
// First range
last_left = lrange;
}
else {
if (lrange == last_right+1) {
// Extend previous range, don't print
}
else {
(*fp)(spaces, last_left, last_right, esize);
last_left = lrange;
}
}
last_right = rrange;
}
static void generate_mem_ranges_one_rank(
const char *spaces,
uint64_t base,
uint64_t rank,
const struct dim_desc *ddp,
fpp fp,
int esize
)
{
uint64_t lindex = ddp->lindex;
uint64_t lower = ddp->lower;
uint64_t upper = ddp->upper;
uint64_t stride = ddp->stride;
uint64_t size = ddp->size;
OFFLOAD_TRACE(3,
"%s "
"generate_mem_ranges_one_rank(base=%p, rank=%lld, lindex=%lld, "
"lower=%lld, upper=%lld, stride=%lld, size=%lld, esize=%d)\n",
spaces, (void*)base, rank, lindex, lower, upper, stride, size, esize);
if (rank == 1) {
uint64_t lrange, rrange;
if (stride == 1) {
lrange = base + (lower-lindex)*size;
rrange = lrange + (upper-lower+1)*size - 1;
generate_one_range(spaces, lrange, rrange, fp, esize);
}
else {
for (int i=lower-lindex; i<=upper-lindex; i+=stride) {
lrange = base + i*size;
rrange = lrange + size - 1;
generate_one_range(spaces, lrange, rrange, fp, esize);
}
}
}
else {
for (int i=lower-lindex; i<=upper-lindex; i+=stride) {
generate_mem_ranges_one_rank(
spaces, base+i*size, rank-1, ddp+1, fp, esize);
}
}
}
static void generate_mem_ranges(
const char *spaces,
const arr_desc *adp,
bool deref,
fpp fp
)
{
uint64_t esize;
OFFLOAD_TRACE(3,
"%s "
"generate_mem_ranges(adp=%p, deref=%d, fp)\n",
spaces, adp, deref);
last_left = -1;
last_right = -2;
// Element size is derived from last dimension
esize = adp->dim[adp->rank-1].size;
generate_mem_ranges_one_rank(
// For c_cean_var the base addr is the address of the data
// For c_cean_var_ptr the base addr is dereferenced to get to the data
spaces, deref ? *((uint64_t*)(adp->base)) : adp->base,
adp->rank, &adp->dim[0], fp, esize);
(*fp)(spaces, last_left, last_right, esize);
}
// returns offset and length of the data to be transferred
void __arr_data_offset_and_length(
const arr_desc *adp,
int64_t &offset,
int64_t &length
)
{
int64_t rank = adp->rank - 1;
int64_t size = adp->dim[rank].size;
int64_t r_off = 0; // offset from right boundary
// find the rightmost dimension which takes just part of its
// range. We define it if the size of left rank is not equal
// the range's length between upper and lower boungaries
while (rank > 0) {
size *= (adp->dim[rank].upper - adp->dim[rank].lower + 1);
if (size != adp->dim[rank - 1].size) {
break;
}
rank--;
}
offset = (adp->dim[rank].lower - adp->dim[rank].lindex) *
adp->dim[rank].size;
// find gaps both from the left - offset and from the right - r_off
for (rank--; rank >= 0; rank--) {
offset += (adp->dim[rank].lower - adp->dim[rank].lindex) *
adp->dim[rank].size;
r_off += adp->dim[rank].size -
(adp->dim[rank + 1].upper - adp->dim[rank + 1].lindex + 1) *
adp->dim[rank + 1].size;
}
length = (adp->dim[0].upper - adp->dim[0].lindex + 1) *
adp->dim[0].size - offset - r_off;
}
#if OFFLOAD_DEBUG > 0
void print_range(
const char *spaces,
uint64_t low,
uint64_t high,
int esize
)
{
char buffer[1024];
char number[32];
OFFLOAD_TRACE(3, "%s print_range(low=%p, high=%p, esize=%d)\n",
spaces, (void*)low, (void*)high, esize);
if (console_enabled < 4) {
return;
}
OFFLOAD_TRACE(4, "%s values:\n", spaces);
int count = 0;
buffer[0] = '\0';
while (low <= high)
{
switch (esize)
{
case 1:
sprintf(number, "%d ", *((char *)low));
low += 1;
break;
case 2:
sprintf(number, "%d ", *((short *)low));
low += 2;
break;
case 4:
sprintf(number, "%d ", *((int *)low));
low += 4;
break;
default:
sprintf(number, "0x%016x ", *((uint64_t *)low));
low += 8;
break;
}
strcat(buffer, number);
count++;
if (count == 10) {
OFFLOAD_TRACE(4, "%s %s\n", spaces, buffer);
count = 0;
buffer[0] = '\0';
}
}
if (count != 0) {
OFFLOAD_TRACE(4, "%s %s\n", spaces, buffer);
}
}
void __arr_desc_dump(
const char *spaces,
const char *name,
const arr_desc *adp,
bool deref
)
{
OFFLOAD_TRACE(2, "%s%s CEAN expression %p\n", spaces, name, adp);
if (adp != 0) {
OFFLOAD_TRACE(2, "%s base=%llx, rank=%lld\n",
spaces, adp->base, adp->rank);
for (int i = 0; i < adp->rank; i++) {
OFFLOAD_TRACE(2,
"%s dimension %d: size=%lld, lindex=%lld, "
"lower=%lld, upper=%lld, stride=%lld\n",
spaces, i, adp->dim[i].size, adp->dim[i].lindex,
adp->dim[i].lower, adp->dim[i].upper,
adp->dim[i].stride);
}
// For c_cean_var the base addr is the address of the data
// For c_cean_var_ptr the base addr is dereferenced to get to the data
generate_mem_ranges(spaces, adp, deref, &print_range);
}
}
#endif // OFFLOAD_DEBUG

View File

@@ -0,0 +1,101 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
#ifndef CEAN_UTIL_H_INCLUDED
#define CEAN_UTIL_H_INCLUDED
#if MPSS_VERSION > 33
#include <source/COIBuffer_source.h>
#endif
#include <stdint.h>
#if MPSS_VERSION <= 33
// CEAN expression representation
struct dim_desc {
int64_t size; // Length of data type
int64_t lindex; // Lower index
int64_t lower; // Lower section bound
int64_t upper; // Upper section bound
int64_t stride; // Stride
};
struct arr_desc {
int64_t base; // Base address
int64_t rank; // Rank of array
dim_desc dim[1];
};
#endif
struct CeanReadDim {
int64_t count; // The number of elements in this dimension
int64_t size; // The number of bytes between successive
// elements in this dimension.
};
struct CeanReadRanges {
void * ptr;
int64_t current_number; // the number of ranges read
int64_t range_max_number; // number of contiguous ranges
int64_t range_size; // size of max contiguous range
int last_noncont_ind; // size of Dim array
int64_t init_offset; // offset of 1-st element from array left bound
CeanReadDim Dim[1];
};
// array descriptor length
#define __arr_desc_length(rank) \
(sizeof(int64_t) + sizeof(dim_desc) * (rank))
// returns offset and length of the data to be transferred
void __arr_data_offset_and_length(const arr_desc *adp,
int64_t &offset,
int64_t &length);
// define if data array described by argument is contiguous one
bool is_arr_desc_contiguous(const arr_desc *ap);
// allocate element of CeanReadRanges type initialized
// to read consequently contiguous ranges described by "ap" argument
CeanReadRanges * init_read_ranges_arr_desc(const arr_desc *ap);
// check if ranges described by 1 argument could be transferred into ranges
// described by 2-nd one
bool cean_ranges_match(
CeanReadRanges * read_rng1,
CeanReadRanges * read_rng2
);
// first argument - returned value by call to init_read_ranges_arr_desc.
// returns true if offset and length of next range is set successfuly.
// returns false if the ranges is over.
bool get_next_range(
CeanReadRanges * read_rng,
int64_t *offset
);
// returns number of transferred bytes
int64_t cean_get_transf_size(CeanReadRanges * read_rng);
#if OFFLOAD_DEBUG > 0
// prints array descriptor contents to stderr
void __arr_desc_dump(
const char *spaces,
const char *name,
const arr_desc *adp,
bool dereference);
#else
#define __arr_desc_dump(
spaces,
name,
adp,
dereference)
#endif // OFFLOAD_DEBUG
#endif // CEAN_UTIL_H_INCLUDED

View File

@@ -0,0 +1,350 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
// The COI host interface
#include "coi_client.h"
#include "../offload_common.h"
namespace COI {
#define COI_VERSION1 "COI_1.0"
#define COI_VERSION2 "COI_2.0"
bool is_available;
static void* lib_handle;
// pointers to functions from COI library
COIRESULT (*EngineGetCount)(COI_ISA_TYPE, uint32_t*);
COIRESULT (*EngineGetHandle)(COI_ISA_TYPE, uint32_t, COIENGINE*);
COIRESULT (*ProcessCreateFromMemory)(COIENGINE, const char*, const void*,
uint64_t, int, const char**, uint8_t,
const char**, uint8_t, const char*,
uint64_t, const char*, const char*,
uint64_t, COIPROCESS*);
COIRESULT (*ProcessDestroy)(COIPROCESS, int32_t, uint8_t, int8_t*, uint32_t*);
COIRESULT (*ProcessGetFunctionHandles)(COIPROCESS, uint32_t, const char**,
COIFUNCTION*);
COIRESULT (*ProcessLoadLibraryFromMemory)(COIPROCESS, const void*, uint64_t,
const char*, const char*,
const char*, uint64_t, uint32_t,
COILIBRARY*);
COIRESULT (*ProcessRegisterLibraries)(uint32_t, const void**, const uint64_t*,
const char**, const uint64_t*);
COIRESULT (*PipelineCreate)(COIPROCESS, COI_CPU_MASK, uint32_t, COIPIPELINE*);
COIRESULT (*PipelineDestroy)(COIPIPELINE);
COIRESULT (*PipelineRunFunction)(COIPIPELINE, COIFUNCTION, uint32_t,
const COIBUFFER*, const COI_ACCESS_FLAGS*,
uint32_t, const COIEVENT*, const void*,
uint16_t, void*, uint16_t, COIEVENT*);
COIRESULT (*BufferCreate)(uint64_t, COI_BUFFER_TYPE, uint32_t, const void*,
uint32_t, const COIPROCESS*, COIBUFFER*);
COIRESULT (*BufferCreateFromMemory)(uint64_t, COI_BUFFER_TYPE, uint32_t,
void*, uint32_t, const COIPROCESS*,
COIBUFFER*);
COIRESULT (*BufferDestroy)(COIBUFFER);
COIRESULT (*BufferMap)(COIBUFFER, uint64_t, uint64_t, COI_MAP_TYPE, uint32_t,
const COIEVENT*, COIEVENT*, COIMAPINSTANCE*, void**);
COIRESULT (*BufferUnmap)(COIMAPINSTANCE, uint32_t, const COIEVENT*, COIEVENT*);
COIRESULT (*BufferWrite)(COIBUFFER, uint64_t, const void*, uint64_t,
COI_COPY_TYPE, uint32_t, const COIEVENT*, COIEVENT*);
COIRESULT (*BufferRead)(COIBUFFER, uint64_t, void*, uint64_t, COI_COPY_TYPE,
uint32_t, const COIEVENT*, COIEVENT*);
COIRESULT (*BufferCopy)(COIBUFFER, COIBUFFER, uint64_t, uint64_t, uint64_t,
COI_COPY_TYPE, uint32_t, const COIEVENT*, COIEVENT*);
COIRESULT (*BufferGetSinkAddress)(COIBUFFER, uint64_t*);
COIRESULT (*BufferSetState)(COIBUFFER, COIPROCESS, COI_BUFFER_STATE,
COI_BUFFER_MOVE_FLAG, uint32_t,
const COIEVENT*, COIEVENT*);
COIRESULT (*EventWait)(uint16_t, const COIEVENT*, int32_t, uint8_t, uint32_t*,
uint32_t*);
uint64_t (*PerfGetCycleFrequency)(void);
bool init(void)
{
#ifndef TARGET_WINNT
const char *lib_name = "libcoi_host.so.0";
#else // TARGET_WINNT
const char *lib_name = "coi_host.dll";
#endif // TARGET_WINNT
OFFLOAD_DEBUG_TRACE(2, "Loading COI library %s ...\n", lib_name);
lib_handle = DL_open(lib_name);
if (lib_handle == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to load the library\n");
return false;
}
EngineGetCount =
(COIRESULT (*)(COI_ISA_TYPE, uint32_t*))
DL_sym(lib_handle, "COIEngineGetCount", COI_VERSION1);
if (EngineGetCount == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIEngineGetCount");
fini();
return false;
}
EngineGetHandle =
(COIRESULT (*)(COI_ISA_TYPE, uint32_t, COIENGINE*))
DL_sym(lib_handle, "COIEngineGetHandle", COI_VERSION1);
if (EngineGetHandle == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIEngineGetHandle");
fini();
return false;
}
ProcessCreateFromMemory =
(COIRESULT (*)(COIENGINE, const char*, const void*, uint64_t, int,
const char**, uint8_t, const char**, uint8_t,
const char*, uint64_t, const char*, const char*,
uint64_t, COIPROCESS*))
DL_sym(lib_handle, "COIProcessCreateFromMemory", COI_VERSION1);
if (ProcessCreateFromMemory == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIProcessCreateFromMemory");
fini();
return false;
}
ProcessDestroy =
(COIRESULT (*)(COIPROCESS, int32_t, uint8_t, int8_t*,
uint32_t*))
DL_sym(lib_handle, "COIProcessDestroy", COI_VERSION1);
if (ProcessDestroy == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIProcessDestroy");
fini();
return false;
}
ProcessGetFunctionHandles =
(COIRESULT (*)(COIPROCESS, uint32_t, const char**, COIFUNCTION*))
DL_sym(lib_handle, "COIProcessGetFunctionHandles", COI_VERSION1);
if (ProcessGetFunctionHandles == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIProcessGetFunctionHandles");
fini();
return false;
}
ProcessLoadLibraryFromMemory =
(COIRESULT (*)(COIPROCESS, const void*, uint64_t, const char*,
const char*, const char*, uint64_t, uint32_t,
COILIBRARY*))
DL_sym(lib_handle, "COIProcessLoadLibraryFromMemory", COI_VERSION2);
if (ProcessLoadLibraryFromMemory == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIProcessLoadLibraryFromMemory");
fini();
return false;
}
ProcessRegisterLibraries =
(COIRESULT (*)(uint32_t, const void**, const uint64_t*, const char**,
const uint64_t*))
DL_sym(lib_handle, "COIProcessRegisterLibraries", COI_VERSION1);
if (ProcessRegisterLibraries == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIProcessRegisterLibraries");
fini();
return false;
}
PipelineCreate =
(COIRESULT (*)(COIPROCESS, COI_CPU_MASK, uint32_t, COIPIPELINE*))
DL_sym(lib_handle, "COIPipelineCreate", COI_VERSION1);
if (PipelineCreate == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIPipelineCreate");
fini();
return false;
}
PipelineDestroy =
(COIRESULT (*)(COIPIPELINE))
DL_sym(lib_handle, "COIPipelineDestroy", COI_VERSION1);
if (PipelineDestroy == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIPipelineDestroy");
fini();
return false;
}
PipelineRunFunction =
(COIRESULT (*)(COIPIPELINE, COIFUNCTION, uint32_t, const COIBUFFER*,
const COI_ACCESS_FLAGS*, uint32_t, const COIEVENT*,
const void*, uint16_t, void*, uint16_t, COIEVENT*))
DL_sym(lib_handle, "COIPipelineRunFunction", COI_VERSION1);
if (PipelineRunFunction == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIPipelineRunFunction");
fini();
return false;
}
BufferCreate =
(COIRESULT (*)(uint64_t, COI_BUFFER_TYPE, uint32_t, const void*,
uint32_t, const COIPROCESS*, COIBUFFER*))
DL_sym(lib_handle, "COIBufferCreate", COI_VERSION1);
if (BufferCreate == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIBufferCreate");
fini();
return false;
}
BufferCreateFromMemory =
(COIRESULT (*)(uint64_t, COI_BUFFER_TYPE, uint32_t, void*,
uint32_t, const COIPROCESS*, COIBUFFER*))
DL_sym(lib_handle, "COIBufferCreateFromMemory", COI_VERSION1);
if (BufferCreateFromMemory == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIBufferCreateFromMemory");
fini();
return false;
}
BufferDestroy =
(COIRESULT (*)(COIBUFFER))
DL_sym(lib_handle, "COIBufferDestroy", COI_VERSION1);
if (BufferDestroy == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIBufferDestroy");
fini();
return false;
}
BufferMap =
(COIRESULT (*)(COIBUFFER, uint64_t, uint64_t, COI_MAP_TYPE, uint32_t,
const COIEVENT*, COIEVENT*, COIMAPINSTANCE*,
void**))
DL_sym(lib_handle, "COIBufferMap", COI_VERSION1);
if (BufferMap == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIBufferMap");
fini();
return false;
}
BufferUnmap =
(COIRESULT (*)(COIMAPINSTANCE, uint32_t, const COIEVENT*,
COIEVENT*))
DL_sym(lib_handle, "COIBufferUnmap", COI_VERSION1);
if (BufferUnmap == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIBufferUnmap");
fini();
return false;
}
BufferWrite =
(COIRESULT (*)(COIBUFFER, uint64_t, const void*, uint64_t,
COI_COPY_TYPE, uint32_t, const COIEVENT*,
COIEVENT*))
DL_sym(lib_handle, "COIBufferWrite", COI_VERSION1);
if (BufferWrite == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIBufferWrite");
fini();
return false;
}
BufferRead =
(COIRESULT (*)(COIBUFFER, uint64_t, void*, uint64_t,
COI_COPY_TYPE, uint32_t,
const COIEVENT*, COIEVENT*))
DL_sym(lib_handle, "COIBufferRead", COI_VERSION1);
if (BufferRead == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIBufferRead");
fini();
return false;
}
BufferCopy =
(COIRESULT (*)(COIBUFFER, COIBUFFER, uint64_t, uint64_t, uint64_t,
COI_COPY_TYPE, uint32_t, const COIEVENT*,
COIEVENT*))
DL_sym(lib_handle, "COIBufferCopy", COI_VERSION1);
if (BufferCopy == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIBufferCopy");
fini();
return false;
}
BufferGetSinkAddress =
(COIRESULT (*)(COIBUFFER, uint64_t*))
DL_sym(lib_handle, "COIBufferGetSinkAddress", COI_VERSION1);
if (BufferGetSinkAddress == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIBufferGetSinkAddress");
fini();
return false;
}
BufferSetState =
(COIRESULT(*)(COIBUFFER, COIPROCESS, COI_BUFFER_STATE,
COI_BUFFER_MOVE_FLAG, uint32_t, const COIEVENT*,
COIEVENT*))
DL_sym(lib_handle, "COIBufferSetState", COI_VERSION1);
if (BufferSetState == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIBufferSetState");
fini();
return false;
}
EventWait =
(COIRESULT (*)(uint16_t, const COIEVENT*, int32_t, uint8_t,
uint32_t*, uint32_t*))
DL_sym(lib_handle, "COIEventWait", COI_VERSION1);
if (EventWait == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIEventWait");
fini();
return false;
}
PerfGetCycleFrequency =
(uint64_t (*)(void))
DL_sym(lib_handle, "COIPerfGetCycleFrequency", COI_VERSION1);
if (PerfGetCycleFrequency == 0) {
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
"COIPerfGetCycleFrequency");
fini();
return false;
}
is_available = true;
return true;
}
void fini(void)
{
is_available = false;
if (lib_handle != 0) {
#ifndef TARGET_WINNT
DL_close(lib_handle);
#endif // TARGET_WINNT
lib_handle = 0;
}
}
} // namespace COI

View File

@@ -0,0 +1,118 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
// The interface between offload library and the COI API on the host
#ifndef COI_CLIENT_H_INCLUDED
#define COI_CLIENT_H_INCLUDED
#include <common/COIPerf_common.h>
#include <source/COIEngine_source.h>
#include <source/COIProcess_source.h>
#include <source/COIPipeline_source.h>
#include <source/COIBuffer_source.h>
#include <source/COIEvent_source.h>
#include <string.h>
#include "../liboffload_error_codes.h"
#include "../offload_util.h"
#define MIC_ENGINES_MAX 128
#if MIC_ENGINES_MAX < COI_MAX_ISA_MIC_DEVICES
#error MIC_ENGINES_MAX need to be increased
#endif
// COI library interface
namespace COI {
extern bool init(void);
extern void fini(void);
extern bool is_available;
// pointers to functions from COI library
extern COIRESULT (*EngineGetCount)(COI_ISA_TYPE, uint32_t*);
extern COIRESULT (*EngineGetHandle)(COI_ISA_TYPE, uint32_t, COIENGINE*);
extern COIRESULT (*ProcessCreateFromMemory)(COIENGINE, const char*,
const void*, uint64_t, int,
const char**, uint8_t,
const char**, uint8_t,
const char*, uint64_t,
const char*,
const char*, uint64_t,
COIPROCESS*);
extern COIRESULT (*ProcessDestroy)(COIPROCESS, int32_t, uint8_t,
int8_t*, uint32_t*);
extern COIRESULT (*ProcessGetFunctionHandles)(COIPROCESS, uint32_t,
const char**,
COIFUNCTION*);
extern COIRESULT (*ProcessLoadLibraryFromMemory)(COIPROCESS,
const void*,
uint64_t,
const char*,
const char*,
const char*,
uint64_t,
uint32_t,
COILIBRARY*);
extern COIRESULT (*ProcessRegisterLibraries)(uint32_t,
const void**,
const uint64_t*,
const char**,
const uint64_t*);
extern COIRESULT (*PipelineCreate)(COIPROCESS, COI_CPU_MASK, uint32_t,
COIPIPELINE*);
extern COIRESULT (*PipelineDestroy)(COIPIPELINE);
extern COIRESULT (*PipelineRunFunction)(COIPIPELINE, COIFUNCTION,
uint32_t, const COIBUFFER*,
const COI_ACCESS_FLAGS*,
uint32_t, const COIEVENT*,
const void*, uint16_t, void*,
uint16_t, COIEVENT*);
extern COIRESULT (*BufferCreate)(uint64_t, COI_BUFFER_TYPE, uint32_t,
const void*, uint32_t,
const COIPROCESS*, COIBUFFER*);
extern COIRESULT (*BufferCreateFromMemory)(uint64_t, COI_BUFFER_TYPE,
uint32_t, void*,
uint32_t, const COIPROCESS*,
COIBUFFER*);
extern COIRESULT (*BufferDestroy)(COIBUFFER);
extern COIRESULT (*BufferMap)(COIBUFFER, uint64_t, uint64_t,
COI_MAP_TYPE, uint32_t, const COIEVENT*,
COIEVENT*, COIMAPINSTANCE*, void**);
extern COIRESULT (*BufferUnmap)(COIMAPINSTANCE, uint32_t,
const COIEVENT*, COIEVENT*);
extern COIRESULT (*BufferWrite)(COIBUFFER, uint64_t, const void*,
uint64_t, COI_COPY_TYPE, uint32_t,
const COIEVENT*, COIEVENT*);
extern COIRESULT (*BufferRead)(COIBUFFER, uint64_t, void*, uint64_t,
COI_COPY_TYPE, uint32_t,
const COIEVENT*, COIEVENT*);
extern COIRESULT (*BufferCopy)(COIBUFFER, COIBUFFER, uint64_t, uint64_t,
uint64_t, COI_COPY_TYPE, uint32_t,
const COIEVENT*, COIEVENT*);
extern COIRESULT (*BufferGetSinkAddress)(COIBUFFER, uint64_t*);
extern COIRESULT (*BufferSetState)(COIBUFFER, COIPROCESS, COI_BUFFER_STATE,
COI_BUFFER_MOVE_FLAG, uint32_t,
const COIEVENT*, COIEVENT*);
extern COIRESULT (*EventWait)(uint16_t, const COIEVENT*, int32_t,
uint8_t, uint32_t*, uint32_t*);
extern uint64_t (*PerfGetCycleFrequency)(void);
} // namespace COI
#endif // COI_CLIENT_H_INCLUDED

View File

@@ -0,0 +1,130 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
// The COI interface on the target
#include "coi_server.h"
#include "../offload_target.h"
#include "../offload_timer.h"
#ifdef MYO_SUPPORT
#include "../offload_myo_target.h" // for __offload_myoLibInit/Fini
#endif // MYO_SUPPORT
COINATIVELIBEXPORT
void server_compute(
uint32_t buffer_count,
void** buffers,
uint64_t* buffers_len,
void* misc_data,
uint16_t misc_data_len,
void* return_data,
uint16_t return_data_len
)
{
OffloadDescriptor::offload(buffer_count, buffers,
misc_data, misc_data_len,
return_data, return_data_len);
}
COINATIVELIBEXPORT
void server_init(
uint32_t buffer_count,
void** buffers,
uint64_t* buffers_len,
void* misc_data,
uint16_t misc_data_len,
void* return_data,
uint16_t return_data_len
)
{
struct init_data {
int device_index;
int devices_total;
int console_level;
int offload_report_level;
} *data = (struct init_data*) misc_data;
// set device index and number of total devices
mic_index = data->device_index;
mic_engines_total = data->devices_total;
// initialize trace level
console_enabled = data->console_level;
offload_report_level = data->offload_report_level;
// return back the process id
*((pid_t*) return_data) = getpid();
}
COINATIVELIBEXPORT
void server_var_table_size(
uint32_t buffer_count,
void** buffers,
uint64_t* buffers_len,
void* misc_data,
uint16_t misc_data_len,
void* return_data,
uint16_t return_data_len
)
{
struct Params {
int64_t nelems;
int64_t length;
} *params;
params = static_cast<Params*>(return_data);
params->length = __offload_vars.table_size(params->nelems);
}
COINATIVELIBEXPORT
void server_var_table_copy(
uint32_t buffer_count,
void** buffers,
uint64_t* buffers_len,
void* misc_data,
uint16_t misc_data_len,
void* return_data,
uint16_t return_data_len
)
{
__offload_vars.table_copy(buffers[0], *static_cast<int64_t*>(misc_data));
}
#ifdef MYO_SUPPORT
// temporary workaround for blocking behavior of myoiLibInit/Fini calls
COINATIVELIBEXPORT
void server_myoinit(
uint32_t buffer_count,
void** buffers,
uint64_t* buffers_len,
void* misc_data,
uint16_t misc_data_len,
void* return_data,
uint16_t return_data_len
)
{
__offload_myoLibInit();
}
COINATIVELIBEXPORT
void server_myofini(
uint32_t buffer_count,
void** buffers,
uint64_t* buffers_len,
void* misc_data,
uint16_t misc_data_len,
void* return_data,
uint16_t return_data_len
)
{
__offload_myoLibFini();
}
#endif // MYO_SUPPORT

View File

@@ -0,0 +1,74 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
//The interface between offload library and the COI API on the target.
#ifndef COI_SERVER_H_INCLUDED
#define COI_SERVER_H_INCLUDED
#include <common/COIEngine_common.h>
#include <common/COIPerf_common.h>
#include <sink/COIProcess_sink.h>
#include <sink/COIPipeline_sink.h>
#include <sink/COIBuffer_sink.h>
#include <list>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "../liboffload_error_codes.h"
// wrappers for COI API
#define PipelineStartExecutingRunFunctions() \
{ \
COIRESULT res = COIPipelineStartExecutingRunFunctions(); \
if (res != COI_SUCCESS) { \
LIBOFFLOAD_ERROR(c_pipeline_start_run_funcs, mic_index, res); \
exit(1); \
} \
}
#define ProcessWaitForShutdown() \
{ \
COIRESULT res = COIProcessWaitForShutdown(); \
if (res != COI_SUCCESS) { \
LIBOFFLOAD_ERROR(c_process_wait_shutdown, mic_index, res); \
exit(1); \
} \
}
#define BufferAddRef(buf) \
{ \
COIRESULT res = COIBufferAddRef(buf); \
if (res != COI_SUCCESS) { \
LIBOFFLOAD_ERROR(c_buf_add_ref, mic_index, res); \
exit(1); \
} \
}
#define BufferReleaseRef(buf) \
{ \
COIRESULT res = COIBufferReleaseRef(buf); \
if (res != COI_SUCCESS) { \
LIBOFFLOAD_ERROR(c_buf_release_ref, mic_index, res); \
exit(1); \
} \
}
#define EngineGetIndex(index) \
{ \
COI_ISA_TYPE isa_type; \
COIRESULT res = COIEngineGetIndex(&isa_type, index); \
if (res != COI_SUCCESS) { \
LIBOFFLOAD_ERROR(c_get_engine_index, mic_index, res); \
exit(1); \
} \
}
#endif // COI_SERVER_H_INCLUDED

View File

@@ -0,0 +1,323 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
#include "compiler_if_host.h"
#include <malloc.h>
#ifndef TARGET_WINNT
#include <alloca.h>
#endif // TARGET_WINNT
// Global counter on host.
// This variable is used if P2OPT_offload_do_data_persistence == 2.
// The variable used to identify offload constructs contained in one procedure.
// Increment of OFFLOAD_CALL_COUNT is inserted at entries of HOST routines with
// offload constructs.
static int offload_call_count = 0;
extern "C" OFFLOAD OFFLOAD_TARGET_ACQUIRE(
TARGET_TYPE target_type,
int target_number,
int is_optional,
_Offload_status* status,
const char* file,
uint64_t line
)
{
bool retval;
OFFLOAD ofld;
// initialize status
if (status != 0) {
status->result = OFFLOAD_UNAVAILABLE;
status->device_number = -1;
status->data_sent = 0;
status->data_received = 0;
}
// make sure libray is initialized
retval = __offload_init_library();
// OFFLOAD_TIMER_INIT must follow call to __offload_init_library
OffloadHostTimerData * timer_data = OFFLOAD_TIMER_INIT(file, line);
OFFLOAD_TIMER_START(timer_data, c_offload_host_total_offload);
OFFLOAD_TIMER_START(timer_data, c_offload_host_initialize);
// initialize all devices is init_type is on_offload_all
if (retval && __offload_init_type == c_init_on_offload_all) {
for (int i = 0; i < mic_engines_total; i++) {
mic_engines[i].init();
}
}
OFFLOAD_TIMER_STOP(timer_data, c_offload_host_initialize);
OFFLOAD_TIMER_START(timer_data, c_offload_host_target_acquire);
if (target_type == TARGET_HOST) {
// Host always available
retval = true;
}
else if (target_type == TARGET_MIC) {
if (target_number >= -1) {
if (retval) {
if (target_number >= 0) {
// User provided the device number
target_number = target_number % mic_engines_total;
}
else {
// use device 0
target_number = 0;
}
// reserve device in ORSL
if (is_optional) {
if (!ORSL::try_reserve(target_number)) {
target_number = -1;
}
}
else {
if (!ORSL::reserve(target_number)) {
target_number = -1;
}
}
// initialize device
if (target_number >= 0 &&
__offload_init_type == c_init_on_offload) {
OFFLOAD_TIMER_START(timer_data, c_offload_host_initialize);
mic_engines[target_number].init();
OFFLOAD_TIMER_STOP(timer_data, c_offload_host_initialize);
}
}
else {
// fallback to CPU
target_number = -1;
}
if (target_number < 0 || !retval) {
if (!is_optional && status == 0) {
LIBOFFLOAD_ERROR(c_device_is_not_available);
exit(1);
}
retval = false;
}
}
else {
LIBOFFLOAD_ERROR(c_invalid_device_number);
exit(1);
}
}
if (retval) {
ofld = new OffloadDescriptor(target_number, status,
!is_optional, false, timer_data);
OFFLOAD_TIMER_HOST_MIC_NUM(timer_data, target_number);
Offload_Report_Prolog(timer_data);
OFFLOAD_DEBUG_TRACE_1(2, timer_data->offload_number, c_offload_start,
"Starting offload: target_type = %d, "
"number = %d, is_optional = %d\n",
target_type, target_number, is_optional);
OFFLOAD_TIMER_STOP(timer_data, c_offload_host_target_acquire);
}
else {
ofld = NULL;
OFFLOAD_TIMER_STOP(timer_data, c_offload_host_target_acquire);
OFFLOAD_TIMER_STOP(timer_data, c_offload_host_total_offload);
offload_report_free_data(timer_data);
}
return ofld;
}
extern "C" OFFLOAD OFFLOAD_TARGET_ACQUIRE1(
const int* device_num,
const char* file,
uint64_t line
)
{
int target_number;
// make sure libray is initialized and at least one device is available
if (!__offload_init_library()) {
LIBOFFLOAD_ERROR(c_device_is_not_available);
exit(1);
}
// OFFLOAD_TIMER_INIT must follow call to __offload_init_library
OffloadHostTimerData * timer_data = OFFLOAD_TIMER_INIT(file, line);
OFFLOAD_TIMER_START(timer_data, c_offload_host_total_offload);
OFFLOAD_TIMER_START(timer_data, c_offload_host_initialize);
if (__offload_init_type == c_init_on_offload_all) {
for (int i = 0; i < mic_engines_total; i++) {
mic_engines[i].init();
}
}
OFFLOAD_TIMER_STOP(timer_data, c_offload_host_initialize);
OFFLOAD_TIMER_START(timer_data, c_offload_host_target_acquire);
// use default device number if it is not provided
if (device_num != 0) {
target_number = *device_num;
}
else {
target_number = __omp_device_num;
}
// device number should be a non-negative integer value
if (target_number < 0) {
LIBOFFLOAD_ERROR(c_omp_invalid_device_num);
exit(1);
}
// should we do this for OpenMP?
target_number %= mic_engines_total;
// reserve device in ORSL
if (!ORSL::reserve(target_number)) {
LIBOFFLOAD_ERROR(c_device_is_not_available);
exit(1);
}
// initialize device(s)
OFFLOAD_TIMER_START(timer_data, c_offload_host_initialize);
if (__offload_init_type == c_init_on_offload) {
mic_engines[target_number].init();
}
OFFLOAD_TIMER_STOP(timer_data, c_offload_host_initialize);
OFFLOAD ofld =
new OffloadDescriptor(target_number, 0, true, true, timer_data);
OFFLOAD_TIMER_HOST_MIC_NUM(timer_data, target_number);
Offload_Report_Prolog(timer_data);
OFFLOAD_DEBUG_TRACE_1(2, timer_data->offload_number, c_offload_start,
"Starting OpenMP offload, device = %d\n",
target_number);
OFFLOAD_TIMER_STOP(timer_data, c_offload_host_target_acquire);
return ofld;
}
int offload_offload_wrap(
OFFLOAD ofld,
const char *name,
int is_empty,
int num_vars,
VarDesc *vars,
VarDesc2 *vars2,
int num_waits,
const void **waits,
const void **signal,
int entry_id,
const void *stack_addr
)
{
bool ret = ofld->offload(name, is_empty, vars, vars2, num_vars,
waits, num_waits, signal, entry_id, stack_addr);
if (!ret || signal == 0) {
delete ofld;
}
return ret;
}
extern "C" int OFFLOAD_OFFLOAD1(
OFFLOAD ofld,
const char *name,
int is_empty,
int num_vars,
VarDesc *vars,
VarDesc2 *vars2,
int num_waits,
const void **waits,
const void **signal
)
{
return offload_offload_wrap(ofld, name, is_empty,
num_vars, vars, vars2,
num_waits, waits,
signal, NULL, NULL);
}
extern "C" int OFFLOAD_OFFLOAD2(
OFFLOAD ofld,
const char *name,
int is_empty,
int num_vars,
VarDesc *vars,
VarDesc2 *vars2,
int num_waits,
const void** waits,
const void** signal,
int entry_id,
const void *stack_addr
)
{
return offload_offload_wrap(ofld, name, is_empty,
num_vars, vars, vars2,
num_waits, waits,
signal, entry_id, stack_addr);
}
extern "C" int OFFLOAD_OFFLOAD(
OFFLOAD ofld,
const char *name,
int is_empty,
int num_vars,
VarDesc *vars,
VarDesc2 *vars2,
int num_waits,
const void **waits,
const void *signal,
int entry_id,
const void *stack_addr
)
{
// signal is passed by reference now
const void **signal_new = (signal != 0) ? &signal : 0;
const void **waits_new = 0;
int num_waits_new = 0;
// remove NULL values from the list of signals to wait for
if (num_waits > 0) {
waits_new = (const void**) alloca(sizeof(void*) * num_waits);
for (int i = 0; i < num_waits; i++) {
if (waits[i] != 0) {
waits_new[num_waits_new++] = waits[i];
}
}
}
return OFFLOAD_OFFLOAD1(ofld, name, is_empty,
num_vars, vars, vars2,
num_waits_new, waits_new,
signal_new);
}
extern "C" int OFFLOAD_CALL_COUNT()
{
offload_call_count++;
return offload_call_count;
}

View File

@@ -0,0 +1,133 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
/*! \file
\brief The interface between compiler-generated host code and runtime library
*/
#ifndef COMPILER_IF_HOST_H_INCLUDED
#define COMPILER_IF_HOST_H_INCLUDED
#include "offload_host.h"
#define OFFLOAD_TARGET_ACQUIRE OFFLOAD_PREFIX(target_acquire)
#define OFFLOAD_TARGET_ACQUIRE1 OFFLOAD_PREFIX(target_acquire1)
#define OFFLOAD_OFFLOAD OFFLOAD_PREFIX(offload)
#define OFFLOAD_OFFLOAD1 OFFLOAD_PREFIX(offload1)
#define OFFLOAD_OFFLOAD2 OFFLOAD_PREFIX(offload2)
#define OFFLOAD_CALL_COUNT OFFLOAD_PREFIX(offload_call_count)
/*! \fn OFFLOAD_TARGET_ACQUIRE
\brief Attempt to acquire the target.
\param target_type The type of target.
\param target_number The device number.
\param is_optional Whether CPU fall-back is allowed.
\param status Address of variable to hold offload status.
\param file Filename in which this offload occurred.
\param line Line number in the file where this offload occurred.
*/
extern "C" OFFLOAD OFFLOAD_TARGET_ACQUIRE(
TARGET_TYPE target_type,
int target_number,
int is_optional,
_Offload_status* status,
const char* file,
uint64_t line
);
/*! \fn OFFLOAD_TARGET_ACQUIRE1
\brief Acquire the target for offload (OpenMP).
\param device_number Device number or null if not specified.
\param file Filename in which this offload occurred
\param line Line number in the file where this offload occurred.
*/
extern "C" OFFLOAD OFFLOAD_TARGET_ACQUIRE1(
const int* device_number,
const char* file,
uint64_t line
);
/*! \fn OFFLOAD_OFFLOAD1
\brief Run function on target using interface for old data persistence.
\param o Offload descriptor created by OFFLOAD_TARGET_ACQUIRE.
\param name Name of offload entry point.
\param is_empty If no code to execute (e.g. offload_transfer)
\param num_vars Number of variable descriptors.
\param vars Pointer to VarDesc array.
\param vars2 Pointer to VarDesc2 array.
\param num_waits Number of "wait" values.
\param waits Pointer to array of wait values.
\param signal Pointer to signal value or NULL.
*/
extern "C" int OFFLOAD_OFFLOAD1(
OFFLOAD o,
const char *name,
int is_empty,
int num_vars,
VarDesc *vars,
VarDesc2 *vars2,
int num_waits,
const void** waits,
const void** signal
);
/*! \fn OFFLOAD_OFFLOAD2
\brief Run function on target using interface for new data persistence.
\param o Offload descriptor created by OFFLOAD_TARGET_ACQUIRE.
\param name Name of offload entry point.
\param is_empty If no code to execute (e.g. offload_transfer)
\param num_vars Number of variable descriptors.
\param vars Pointer to VarDesc array.
\param vars2 Pointer to VarDesc2 array.
\param num_waits Number of "wait" values.
\param waits Pointer to array of wait values.
\param signal Pointer to signal value or NULL.
\param entry_id A signature for the function doing the offload.
\param stack_addr The stack frame address of the function doing offload.
*/
extern "C" int OFFLOAD_OFFLOAD2(
OFFLOAD o,
const char *name,
int is_empty,
int num_vars,
VarDesc *vars,
VarDesc2 *vars2,
int num_waits,
const void** waits,
const void** signal,
int entry_id,
const void *stack_addr
);
// Run function on target (obsolete).
// @param o OFFLOAD object
// @param name function name
extern "C" int OFFLOAD_OFFLOAD(
OFFLOAD o,
const char *name,
int is_empty,
int num_vars,
VarDesc *vars,
VarDesc2 *vars2,
int num_waits,
const void** waits,
const void* signal,
int entry_id = 0,
const void *stack_addr = NULL
);
// Global counter on host.
// This variable is used if P2OPT_offload_do_data_persistence == 2.
// The variable used to identify offload constructs contained in one procedure.
// Call to OFFLOAD_CALL_COUNT() is inserted at HOST on entry of the routine.
extern "C" int OFFLOAD_CALL_COUNT();
#endif // COMPILER_IF_HOST_H_INCLUDED

View File

@@ -0,0 +1,44 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
#include "compiler_if_target.h"
extern "C" void OFFLOAD_TARGET_ENTER(
OFFLOAD ofld,
int vars_total,
VarDesc *vars,
VarDesc2 *vars2
)
{
OFFLOAD_DEBUG_TRACE(3, "%s(%p, %d, %p, %p)\n", __func__, ofld,
vars_total, vars, vars2);
ofld->merge_var_descs(vars, vars2, vars_total);
ofld->scatter_copyin_data();
}
extern "C" void OFFLOAD_TARGET_LEAVE(
OFFLOAD ofld
)
{
OFFLOAD_DEBUG_TRACE(3, "%s(%p)\n", __func__, ofld);
ofld->gather_copyout_data();
}
extern "C" void OFFLOAD_TARGET_MAIN(void)
{
// initialize target part
__offload_target_init();
// pass control to COI
PipelineStartExecutingRunFunctions();
ProcessWaitForShutdown();
OFFLOAD_DEBUG_TRACE(2, "Exiting main...\n");
}

View File

@@ -0,0 +1,50 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
/*! \file
\brief The interface between compiler-generated target code and runtime library
*/
#ifndef COMPILER_IF_TARGET_H_INCLUDED
#define COMPILER_IF_TARGET_H_INCLUDED
#include "offload_target.h"
#define OFFLOAD_TARGET_ENTER OFFLOAD_PREFIX(target_enter)
#define OFFLOAD_TARGET_LEAVE OFFLOAD_PREFIX(target_leave)
#define OFFLOAD_TARGET_MAIN OFFLOAD_PREFIX(target_main)
/*! \fn OFFLOAD_TARGET_ENTER
\brief Fill in variable addresses using VarDesc array.
\brief Then call back the runtime library to fetch data.
\param ofld Offload descriptor created by runtime.
\param var_desc_num Number of variable descriptors.
\param var_desc Pointer to VarDesc array.
\param var_desc2 Pointer to VarDesc2 array.
*/
extern "C" void OFFLOAD_TARGET_ENTER(
OFFLOAD ofld,
int var_desc_num,
VarDesc *var_desc,
VarDesc2 *var_desc2
);
/*! \fn OFFLOAD_TARGET_LEAVE
\brief Call back the runtime library to gather outputs using VarDesc array.
\param ofld Offload descriptor created by OFFLOAD_TARGET_ACQUIRE.
*/
extern "C" void OFFLOAD_TARGET_LEAVE(
OFFLOAD ofld
);
// Entry point for the target application.
extern "C" void OFFLOAD_TARGET_MAIN(void);
#endif // COMPILER_IF_TARGET_H_INCLUDED

View File

@@ -0,0 +1,131 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
#include "offload_common.h"
bool __dv_is_contiguous(const ArrDesc *dvp)
{
if (dvp->Flags & ArrDescFlagsContiguous) {
return true;
}
if (dvp->Rank != 0) {
if (dvp->Dim[0].Mult != dvp->Len) {
return false;
}
for (int i = 1; i < dvp->Rank; i++) {
if (dvp->Dim[i].Mult !=
dvp->Dim[i-1].Extent * dvp->Dim[i-1].Mult) {
return false;
}
}
}
return true;
}
bool __dv_is_allocated(const ArrDesc *dvp)
{
return (dvp->Flags & ArrDescFlagsDefined);
}
uint64_t __dv_data_length(const ArrDesc *dvp)
{
uint64_t size;
if (dvp->Rank == 0) {
size = dvp->Len;
return size;
}
size = dvp->Len;
for (int i = 0; i < dvp->Rank; ++i) {
size += (dvp->Dim[i].Extent-1) * dvp->Dim[i].Mult;
}
return size;
}
uint64_t __dv_data_length(const ArrDesc *dvp, int64_t count)
{
if (dvp->Rank == 0) {
return count;
}
return count * dvp->Dim[0].Mult;
}
// Create CeanReadRanges data for reading contiguous ranges of
// noncontiguous array defined by the argument
CeanReadRanges * init_read_ranges_dv(const ArrDesc *dvp)
{
int64_t len;
int count;
int rank = dvp->Rank;
CeanReadRanges *res = NULL;
if (rank != 0) {
int i = 0;
len = dvp->Len;
if (dvp->Dim[0].Mult == len) {
for (i = 1; i < rank; i++) {
len *= dvp->Dim[i-1].Extent;
if (dvp->Dim[i].Mult != len) {
break;
}
}
}
res = (CeanReadRanges *)malloc(
sizeof(CeanReadRanges) + (rank - i) * sizeof(CeanReadDim));
res -> last_noncont_ind = rank - i - 1;
count = 1;
for (; i < rank; i++) {
res->Dim[rank - i - 1].count = count;
res->Dim[rank - i - 1].size = dvp->Dim[i].Mult;
count *= dvp->Dim[i].Extent;
}
res -> range_max_number = count;
res -> range_size = len;
res -> ptr = (void*)dvp->Base;
res -> current_number = 0;
res -> init_offset = 0;
}
return res;
}
#if OFFLOAD_DEBUG > 0
void __dv_desc_dump(const char *name, const ArrDesc *dvp)
{
OFFLOAD_TRACE(3, "%s DV %p\n", name, dvp);
if (dvp != 0) {
OFFLOAD_TRACE(3,
" dv->Base = 0x%lx\n"
" dv->Len = 0x%lx\n"
" dv->Offset = 0x%lx\n"
" dv->Flags = 0x%lx\n"
" dv->Rank = 0x%lx\n"
" dv->Resrvd = 0x%lx\n",
dvp->Base,
dvp->Len,
dvp->Offset,
dvp->Flags,
dvp->Rank,
dvp->Reserved);
for (int i = 0 ; i < dvp->Rank; i++) {
OFFLOAD_TRACE(3,
" (%d) Extent=%ld, Multiplier=%ld, LowerBound=%ld\n",
i,
dvp->Dim[i].Extent,
dvp->Dim[i].Mult,
dvp->Dim[i].LowerBound);
}
}
}
#endif // OFFLOAD_DEBUG > 0

View File

@@ -0,0 +1,63 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
#ifndef DV_UTIL_H_INCLUDED
#define DV_UTIL_H_INCLUDED
#include <stdint.h>
// Dope vector declarations
#define ArrDescMaxArrayRank 31
// Dope vector flags
#define ArrDescFlagsDefined 1
#define ArrDescFlagsNodealloc 2
#define ArrDescFlagsContiguous 4
typedef int64_t dv_size;
typedef struct DimDesc {
dv_size Extent; // Number of elements in this dimension
dv_size Mult; // Multiplier for this dimension.
// The number of bytes between successive
// elements in this dimension.
dv_size LowerBound; // LowerBound of this dimension
} DimDesc ;
typedef struct ArrDesc {
dv_size Base; // Base address
dv_size Len; // Length of data type, used only for
// character strings.
dv_size Offset;
dv_size Flags; // Flags
dv_size Rank; // Rank of pointer
dv_size Reserved; // reserved for openmp requests
DimDesc Dim[ArrDescMaxArrayRank];
} ArrDesc ;
typedef ArrDesc* pArrDesc;
bool __dv_is_contiguous(const ArrDesc *dvp);
bool __dv_is_allocated(const ArrDesc *dvp);
uint64_t __dv_data_length(const ArrDesc *dvp);
uint64_t __dv_data_length(const ArrDesc *dvp, int64_t nelems);
CeanReadRanges * init_read_ranges_dv(const ArrDesc *dvp);
#if OFFLOAD_DEBUG > 0
void __dv_desc_dump(const char *name, const ArrDesc *dvp);
#else // OFFLOAD_DEBUG
#define __dv_desc_dump(name, dvp)
#endif // OFFLOAD_DEBUG
#endif // DV_UTIL_H_INCLUDED

View File

@@ -0,0 +1,452 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
#include <stdarg.h>
#ifndef va_copy
#define va_copy(dst, src) ((dst) = (src))
#endif
#include "liboffload_msg.h"
#include "liboffload_error_codes.h"
/***********************************************/
/* error-handling function, liboffload_error_support */
/***********************************************/
void __liboffload_error_support(error_types input_tag, ...)
{
va_list args;
va_start(args, input_tag);
switch (input_tag) {
case c_device_is_not_available:
write_message(stderr, msg_c_device_is_not_available, args);
break;
case c_invalid_device_number:
write_message(stderr, msg_c_invalid_device_number, args);
break;
case c_send_func_ptr:
write_message(stderr, msg_c_send_func_ptr, args);
break;
case c_receive_func_ptr:
write_message(stderr, msg_c_receive_func_ptr, args);
break;
case c_offload_malloc:
write_message(stderr, msg_c_offload_malloc, args);
break;
case c_offload1:
write_message(stderr, msg_c_offload1, args);
break;
case c_unknown_var_type:
write_message(stderr, c_unknown_var_type, args);
break;
case c_invalid_env_var_value:
write_message(stderr, msg_c_invalid_env_var_value, args);
break;
case c_invalid_env_var_int_value:
write_message(stderr, msg_c_invalid_env_var_int_value, args);
break;
case c_invalid_env_report_value:
write_message(stderr, msg_c_invalid_env_report_value, args);
break;
case c_offload_signaled1:
write_message(stderr, msg_c_offload_signaled1, args);
break;
case c_offload_signaled2:
write_message(stderr, msg_c_offload_signaled2, args);
break;
case c_myowrapper_checkresult:
write_message(stderr, msg_c_myowrapper_checkresult, args);
break;
case c_myotarget_checkresult:
write_message(stderr, msg_c_myotarget_checkresult, args);
break;
case c_offload_descriptor_offload:
write_message(stderr, msg_c_offload_descriptor_offload, args);
break;
case c_merge_var_descs1:
write_message(stderr, msg_c_merge_var_descs1, args);
break;
case c_merge_var_descs2:
write_message(stderr, msg_c_merge_var_descs2, args);
break;
case c_mic_parse_env_var_list1:
write_message(stderr, msg_c_mic_parse_env_var_list1, args);
break;
case c_mic_parse_env_var_list2:
write_message(stderr, msg_c_mic_parse_env_var_list2, args);
break;
case c_mic_process_exit_ret:
write_message(stderr, msg_c_mic_process_exit_ret, args);
break;
case c_mic_process_exit_sig:
write_message(stderr, msg_c_mic_process_exit_sig, args);
break;
case c_mic_process_exit:
write_message(stderr, msg_c_mic_process_exit, args);
break;
case c_mic_init3:
write_message(stderr, msg_c_mic_init3, args);
break;
case c_mic_init4:
write_message(stderr, msg_c_mic_init4, args);
break;
case c_mic_init5:
write_message(stderr, msg_c_mic_init5, args);
break;
case c_mic_init6:
write_message(stderr, msg_c_mic_init6, args);
break;
case c_no_static_var_data:
write_message(stderr, msg_c_no_static_var_data, args);
break;
case c_no_ptr_data:
write_message(stderr, msg_c_no_ptr_data, args);
break;
case c_get_engine_handle:
write_message(stderr, msg_c_get_engine_handle, args);
break;
case c_get_engine_index:
write_message(stderr, msg_c_get_engine_index, args);
break;
case c_process_create:
write_message(stderr, msg_c_process_create, args);
break;
case c_process_wait_shutdown:
write_message(stderr, msg_c_process_wait_shutdown, args);
break;
case c_process_proxy_flush:
write_message(stderr, msg_c_process_proxy_flush, args);
break;
case c_process_get_func_handles:
write_message(stderr, msg_c_process_get_func_handles, args);
break;
case c_load_library:
write_message(stderr, msg_c_load_library, args);
break;
case c_coipipe_max_number:
write_message(stderr, msg_c_coi_pipeline_max_number, args);
break;
case c_pipeline_create:
write_message(stderr, msg_c_pipeline_create, args);
break;
case c_pipeline_run_func:
write_message(stderr, msg_c_pipeline_run_func, args);
break;
case c_pipeline_start_run_funcs:
write_message(stderr, msg_c_pipeline_start_run_funcs, args);
break;
case c_buf_create:
write_message(stderr, msg_c_buf_create, args);
break;
case c_buf_create_out_of_mem:
write_message(stderr, msg_c_buf_create_out_of_mem, args);
break;
case c_buf_create_from_mem:
write_message(stderr, msg_c_buf_create_from_mem, args);
break;
case c_buf_destroy:
write_message(stderr, msg_c_buf_destroy, args);
break;
case c_buf_map:
write_message(stderr, msg_c_buf_map, args);
break;
case c_buf_unmap:
write_message(stderr, msg_c_buf_unmap, args);
break;
case c_buf_read:
write_message(stderr, msg_c_buf_read, args);
break;
case c_buf_write:
write_message(stderr, msg_c_buf_write, args);
break;
case c_buf_copy:
write_message(stderr, msg_c_buf_copy, args);
break;
case c_buf_get_address:
write_message(stderr, msg_c_buf_get_address, args);
break;
case c_buf_add_ref:
write_message(stderr, msg_c_buf_add_ref, args);
break;
case c_buf_release_ref:
write_message(stderr, msg_c_buf_release_ref, args);
break;
case c_buf_set_state:
write_message(stderr, msg_c_buf_set_state, args);
break;
case c_event_wait:
write_message(stderr, msg_c_event_wait, args);
break;
case c_zero_or_neg_ptr_len:
write_message(stderr, msg_c_zero_or_neg_ptr_len, args);
break;
case c_zero_or_neg_transfer_size:
write_message(stderr, msg_c_zero_or_neg_transfer_size, args);
break;
case c_bad_ptr_mem_range:
write_message(stderr, msg_c_bad_ptr_mem_range, args);
break;
case c_different_src_and_dstn_sizes:
write_message(stderr, msg_c_different_src_and_dstn_sizes, args);
break;
case c_ranges_dont_match:
write_message(stderr, msg_c_ranges_dont_match, args);
break;
case c_destination_is_over:
write_message(stderr, msg_c_destination_is_over, args);
break;
case c_slice_of_noncont_array:
write_message(stderr, msg_c_slice_of_noncont_array, args);
break;
case c_non_contiguous_dope_vector:
write_message(stderr, msg_c_non_contiguous_dope_vector, args);
break;
case c_pointer_array_mismatch:
write_message(stderr, msg_c_pointer_array_mismatch, args);
break;
case c_omp_invalid_device_num_env:
write_message(stderr, msg_c_omp_invalid_device_num_env, args);
break;
case c_omp_invalid_device_num:
write_message(stderr, msg_c_omp_invalid_device_num, args);
break;
case c_unknown_binary_type:
write_message(stderr, msg_c_unknown_binary_type, args);
break;
case c_multiple_target_exes:
write_message(stderr, msg_c_multiple_target_exes, args);
break;
case c_no_target_exe:
write_message(stderr, msg_c_no_target_exe, args);
break;
case c_report_unknown_timer_node:
write_message(stderr, msg_c_report_unknown_timer_node, args);
break;
case c_report_unknown_trace_node:
write_message(stderr, msg_c_report_unknown_trace_node, args);
break;
}
va_end(args);
}
char const * report_get_message_str(error_types input_tag)
{
switch (input_tag) {
case c_report_title:
return (offload_get_message_str(msg_c_report_title));
case c_report_from_file:
return (offload_get_message_str(msg_c_report_from_file));
case c_report_offload:
return (offload_get_message_str(msg_c_report_offload));
case c_report_mic:
return (offload_get_message_str(msg_c_report_mic));
case c_report_file:
return (offload_get_message_str(msg_c_report_file));
case c_report_line:
return (offload_get_message_str(msg_c_report_line));
case c_report_host:
return (offload_get_message_str(msg_c_report_host));
case c_report_tag:
return (offload_get_message_str(msg_c_report_tag));
case c_report_cpu_time:
return (offload_get_message_str(msg_c_report_cpu_time));
case c_report_seconds:
return (offload_get_message_str(msg_c_report_seconds));
case c_report_cpu_to_mic_data:
return (offload_get_message_str(msg_c_report_cpu_to_mic_data));
case c_report_bytes:
return (offload_get_message_str(msg_c_report_bytes));
case c_report_mic_time:
return (offload_get_message_str(msg_c_report_mic_time));
case c_report_mic_to_cpu_data:
return (offload_get_message_str(msg_c_report_mic_to_cpu_data));
case c_report_compute:
return (offload_get_message_str(msg_c_report_compute));
case c_report_copyin_data:
return (offload_get_message_str(msg_c_report_copyin_data));
case c_report_copyout_data:
return (offload_get_message_str(msg_c_report_copyout_data));
case c_report_create_buf_host:
return (offload_get_message_str(c_report_create_buf_host));
case c_report_create_buf_mic:
return (offload_get_message_str(msg_c_report_create_buf_mic));
case c_report_destroy:
return (offload_get_message_str(msg_c_report_destroy));
case c_report_gather_copyin_data:
return (offload_get_message_str(msg_c_report_gather_copyin_data));
case c_report_gather_copyout_data:
return (offload_get_message_str(msg_c_report_gather_copyout_data));
case c_report_state_signal:
return (offload_get_message_str(msg_c_report_state_signal));
case c_report_signal:
return (offload_get_message_str(msg_c_report_signal));
case c_report_wait:
return (offload_get_message_str(msg_c_report_wait));
case c_report_init:
return (offload_get_message_str(msg_c_report_init));
case c_report_init_func:
return (offload_get_message_str(msg_c_report_init_func));
case c_report_logical_card:
return (offload_get_message_str(msg_c_report_logical_card));
case c_report_mic_myo_fptr:
return (offload_get_message_str(msg_c_report_mic_myo_fptr));
case c_report_mic_myo_shared:
return (offload_get_message_str(msg_c_report_mic_myo_shared));
case c_report_myoacquire:
return (offload_get_message_str(msg_c_report_myoacquire));
case c_report_myofini:
return (offload_get_message_str(msg_c_report_myofini));
case c_report_myoinit:
return (offload_get_message_str(msg_c_report_myoinit));
case c_report_myoregister:
return (offload_get_message_str(msg_c_report_myoregister));
case c_report_myorelease:
return (offload_get_message_str(msg_c_report_myorelease));
case c_report_myosharedalignedfree:
return (
offload_get_message_str(msg_c_report_myosharedalignedfree));
case c_report_myosharedalignedmalloc:
return (
offload_get_message_str(msg_c_report_myosharedalignedmalloc));
case c_report_myosharedfree:
return (offload_get_message_str(msg_c_report_myosharedfree));
case c_report_myosharedmalloc:
return (offload_get_message_str(msg_c_report_myosharedmalloc));
case c_report_physical_card:
return (offload_get_message_str(msg_c_report_physical_card));
case c_report_receive_pointer_data:
return (
offload_get_message_str(msg_c_report_receive_pointer_data));
case c_report_received_pointer_data:
return (
offload_get_message_str(msg_c_report_received_pointer_data));
case c_report_register:
return (offload_get_message_str(msg_c_report_register));
case c_report_scatter_copyin_data:
return (offload_get_message_str(msg_c_report_scatter_copyin_data));
case c_report_scatter_copyout_data:
return (
offload_get_message_str(msg_c_report_scatter_copyout_data));
case c_report_send_pointer_data:
return (offload_get_message_str(msg_c_report_send_pointer_data));
case c_report_sent_pointer_data:
return (offload_get_message_str(msg_c_report_sent_pointer_data));
case c_report_start:
return (offload_get_message_str(msg_c_report_start));
case c_report_start_target_func:
return (offload_get_message_str(msg_c_report_start_target_func));
case c_report_state:
return (offload_get_message_str(msg_c_report_state));
case c_report_unregister:
return (offload_get_message_str(msg_c_report_unregister));
case c_report_var:
return (offload_get_message_str(msg_c_report_var));
default:
LIBOFFLOAD_ERROR(c_report_unknown_trace_node);
abort();
}
}
char const * report_get_host_stage_str(int i)
{
switch (i) {
case c_offload_host_total_offload:
return (
offload_get_message_str(msg_c_report_host_total_offload_time));
case c_offload_host_initialize:
return (offload_get_message_str(msg_c_report_host_initialize));
case c_offload_host_target_acquire:
return (
offload_get_message_str(msg_c_report_host_target_acquire));
case c_offload_host_wait_deps:
return (offload_get_message_str(msg_c_report_host_wait_deps));
case c_offload_host_setup_buffers:
return (offload_get_message_str(msg_c_report_host_setup_buffers));
case c_offload_host_alloc_buffers:
return (offload_get_message_str(msg_c_report_host_alloc_buffers));
case c_offload_host_setup_misc_data:
return (
offload_get_message_str(msg_c_report_host_setup_misc_data));
case c_offload_host_alloc_data_buffer:
return (
offload_get_message_str(msg_c_report_host_alloc_data_buffer));
case c_offload_host_send_pointers:
return (offload_get_message_str(msg_c_report_host_send_pointers));
case c_offload_host_gather_inputs:
return (offload_get_message_str(msg_c_report_host_gather_inputs));
case c_offload_host_map_in_data_buffer:
return (
offload_get_message_str(msg_c_report_host_map_in_data_buffer));
case c_offload_host_unmap_in_data_buffer:
return (offload_get_message_str(
msg_c_report_host_unmap_in_data_buffer));
case c_offload_host_start_compute:
return (offload_get_message_str(msg_c_report_host_start_compute));
case c_offload_host_wait_compute:
return (offload_get_message_str(msg_c_report_host_wait_compute));
case c_offload_host_start_buffers_reads:
return (offload_get_message_str(
msg_c_report_host_start_buffers_reads));
case c_offload_host_scatter_outputs:
return (
offload_get_message_str(msg_c_report_host_scatter_outputs));
case c_offload_host_map_out_data_buffer:
return (offload_get_message_str(
msg_c_report_host_map_out_data_buffer));
case c_offload_host_unmap_out_data_buffer:
return (offload_get_message_str(
msg_c_report_host_unmap_out_data_buffer));
case c_offload_host_wait_buffers_reads:
return (
offload_get_message_str(msg_c_report_host_wait_buffers_reads));
case c_offload_host_destroy_buffers:
return (
offload_get_message_str(msg_c_report_host_destroy_buffers));
default:
LIBOFFLOAD_ERROR(c_report_unknown_timer_node);
abort();
}
}
char const * report_get_target_stage_str(int i)
{
switch (i) {
case c_offload_target_total_time:
return (offload_get_message_str(msg_c_report_target_total_time));
case c_offload_target_descriptor_setup:
return (
offload_get_message_str(msg_c_report_target_descriptor_setup));
case c_offload_target_func_lookup:
return (offload_get_message_str(msg_c_report_target_func_lookup));
case c_offload_target_func_time:
return (offload_get_message_str(msg_c_report_target_func_time));
case c_offload_target_scatter_inputs:
return (
offload_get_message_str(msg_c_report_target_scatter_inputs));
case c_offload_target_add_buffer_refs:
return (
offload_get_message_str(msg_c_report_target_add_buffer_refs));
case c_offload_target_compute:
return (offload_get_message_str(msg_c_report_target_compute));
case c_offload_target_gather_outputs:
return (offload_get_message_str
(msg_c_report_target_gather_outputs));
case c_offload_target_release_buffer_refs:
return (offload_get_message_str(
msg_c_report_target_release_buffer_refs));
default:
LIBOFFLOAD_ERROR(c_report_unknown_timer_node);
abort();
}
}

View File

@@ -0,0 +1,276 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
#if !defined(LIBOFFLOAD_ERROR_CODES_H)
#define LIBOFFLOAD_ERROR_CODES_H
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
typedef enum
{
c_device_is_not_available = 0,
c_invalid_device_number,
c_offload1,
c_unknown_var_type,
c_send_func_ptr,
c_receive_func_ptr,
c_offload_malloc,
c_invalid_env_var_value,
c_invalid_env_var_int_value,
c_invalid_env_report_value,
c_offload_signaled1,
c_offload_signaled2,
c_myotarget_checkresult,
c_myowrapper_checkresult,
c_offload_descriptor_offload,
c_merge_var_descs1,
c_merge_var_descs2,
c_mic_parse_env_var_list1,
c_mic_parse_env_var_list2,
c_mic_process_exit_ret,
c_mic_process_exit_sig,
c_mic_process_exit,
c_mic_init3,
c_mic_init4,
c_mic_init5,
c_mic_init6,
c_no_static_var_data,
c_no_ptr_data,
c_get_engine_handle,
c_get_engine_index,
c_process_create,
c_process_get_func_handles,
c_process_wait_shutdown,
c_process_proxy_flush,
c_load_library,
c_pipeline_create,
c_pipeline_run_func,
c_pipeline_start_run_funcs,
c_buf_create,
c_buf_create_out_of_mem,
c_buf_create_from_mem,
c_buf_destroy,
c_buf_map,
c_buf_unmap,
c_buf_read,
c_buf_write,
c_buf_copy,
c_buf_get_address,
c_buf_add_ref,
c_buf_release_ref,
c_buf_set_state,
c_event_wait,
c_zero_or_neg_ptr_len,
c_zero_or_neg_transfer_size,
c_bad_ptr_mem_range,
c_different_src_and_dstn_sizes,
c_ranges_dont_match,
c_destination_is_over,
c_slice_of_noncont_array,
c_non_contiguous_dope_vector,
c_pointer_array_mismatch,
c_omp_invalid_device_num_env,
c_omp_invalid_device_num,
c_unknown_binary_type,
c_multiple_target_exes,
c_no_target_exe,
c_report_host,
c_report_target,
c_report_title,
c_report_from_file,
c_report_file,
c_report_line,
c_report_tag,
c_report_seconds,
c_report_bytes,
c_report_mic,
c_report_cpu_time,
c_report_cpu_to_mic_data,
c_report_mic_time,
c_report_mic_to_cpu_data,
c_report_unknown_timer_node,
c_report_unknown_trace_node,
c_report_offload,
c_report_w_tag,
c_report_state,
c_report_start,
c_report_init,
c_report_logical_card,
c_report_physical_card,
c_report_register,
c_report_init_func,
c_report_create_buf_host,
c_report_create_buf_mic,
c_report_send_pointer_data,
c_report_sent_pointer_data,
c_report_gather_copyin_data,
c_report_copyin_data,
c_report_state_signal,
c_report_signal,
c_report_wait,
c_report_compute,
c_report_receive_pointer_data,
c_report_received_pointer_data,
c_report_start_target_func,
c_report_var,
c_report_scatter_copyin_data,
c_report_gather_copyout_data,
c_report_scatter_copyout_data,
c_report_copyout_data,
c_report_unregister,
c_report_destroy,
c_report_myoinit,
c_report_myoregister,
c_report_myofini,
c_report_mic_myo_shared,
c_report_mic_myo_fptr,
c_report_myosharedmalloc,
c_report_myosharedfree,
c_report_myosharedalignedmalloc,
c_report_myosharedalignedfree,
c_report_myoacquire,
c_report_myorelease,
c_coipipe_max_number
} error_types;
enum OffloadHostPhase {
// Total time on host for entire offload
c_offload_host_total_offload = 0,
// Time to load target binary
c_offload_host_initialize,
// Time to acquire lrb availability dynamically
c_offload_host_target_acquire,
// Time to wait for dependencies
c_offload_host_wait_deps,
// Time to allocate pointer buffers, initiate writes for pointers
// and calculate size of copyin/copyout buffer
c_offload_host_setup_buffers,
// Time to allocate pointer buffers
c_offload_host_alloc_buffers,
// Time to initialize misc data
c_offload_host_setup_misc_data,
// Time to allocate copyin/copyout buffer
c_offload_host_alloc_data_buffer,
// Time to initiate writes from host pointers to buffers
c_offload_host_send_pointers,
// Time to Gather IN data of offload into buffer
c_offload_host_gather_inputs,
// Time to map buffer
c_offload_host_map_in_data_buffer,
// Time to unmap buffer
c_offload_host_unmap_in_data_buffer,
// Time to start remote function call that does computation on lrb
c_offload_host_start_compute,
// Time to wait for compute to finish
c_offload_host_wait_compute,
// Time to initiate reads from pointer buffers
c_offload_host_start_buffers_reads,
// Time to update host variabels with OUT data from buffer
c_offload_host_scatter_outputs,
// Time to map buffer
c_offload_host_map_out_data_buffer,
// Time to unmap buffer
c_offload_host_unmap_out_data_buffer,
// Time to wait reads from buffers to finish
c_offload_host_wait_buffers_reads,
// Time to destroy buffers that are no longer needed
c_offload_host_destroy_buffers,
// LAST TIME MONITOR
c_offload_host_max_phase
};
enum OffloadTargetPhase {
// Total time spent on the target
c_offload_target_total_time = 0,
// Time to initialize offload descriptor
c_offload_target_descriptor_setup,
// Time to find target entry point in lookup table
c_offload_target_func_lookup,
// Total time spend executing offload entry
c_offload_target_func_time,
// Time to initialize target variables with IN values from buffer
c_offload_target_scatter_inputs,
// Time to add buffer reference for pointer buffers
c_offload_target_add_buffer_refs,
// Total time on lrb for computation
c_offload_target_compute,
// On lrb, time to copy OUT into buffer
c_offload_target_gather_outputs,
// Time to release buffer references
c_offload_target_release_buffer_refs,
// LAST TIME MONITOR
c_offload_target_max_phase
};
#ifdef __cplusplus
extern "C" {
#endif
void __liboffload_error_support(error_types input_tag, ...);
void __liboffload_report_support(error_types input_tag, ...);
char const *offload_get_message_str(int msgCode);
char const * report_get_message_str(error_types input_tag);
char const * report_get_host_stage_str(int i);
char const * report_get_target_stage_str(int i);
#ifdef __cplusplus
}
#endif
#define test_msg_cat(nm, msg) \
fprintf(stderr, "\t TEST for %s \n \t", nm); \
__liboffload_error_support(msg);
#define test_msg_cat1(nm, msg, ...) \
fprintf(stderr, "\t TEST for %s \n \t", nm); \
__liboffload_error_support(msg, __VA_ARGS__);
void write_message(FILE * file, int msgCode, va_list args_p);
#define LIBOFFLOAD_ERROR __liboffload_error_support
#ifdef TARGET_WINNT
#define LIBOFFLOAD_ABORT \
_set_abort_behavior(0, _WRITE_ABORT_MSG); \
abort()
#else
#define LIBOFFLOAD_ABORT \
abort()
#endif
#endif // !defined(LIBOFFLOAD_ERROR_CODES_H)

View File

@@ -0,0 +1,35 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
// ===========================================================================
// Bring in the static string table and the enumerations for indexing into
// it.
// ===========================================================================
#include "liboffload_msg.h"
# define DYNART_STDERR_PUTS(__message_text__) fputs((__message_text__),stderr)
// ===========================================================================
// Now the code for accessing the message catalogs
// ===========================================================================
void write_message(FILE * file, int msgCode) {
fputs(MESSAGE_TABLE_NAME[ msgCode ], file);
fflush(file);
}
char const *offload_get_message_str(int msgCode) {
return MESSAGE_TABLE_NAME[ msgCode ];
}

View File

@@ -0,0 +1,326 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
// file: liboffload_msg.h
enum {
__dummy__ = 0,
msg_c_device_is_not_available,
msg_c_invalid_device_number,
msg_c_send_func_ptr,
msg_c_receive_func_ptr,
msg_c_offload_malloc,
msg_c_offload1,
msg_c_unknown_var_type,
msg_c_invalid_env_var_value,
msg_c_invalid_env_var_int_value,
msg_c_invalid_env_report_value,
msg_c_offload_signaled1,
msg_c_offload_signaled2,
msg_c_myowrapper_checkresult,
msg_c_myotarget_checkresult,
msg_c_offload_descriptor_offload,
msg_c_merge_var_descs1,
msg_c_merge_var_descs2,
msg_c_mic_parse_env_var_list1,
msg_c_mic_parse_env_var_list2,
msg_c_mic_process_exit_ret,
msg_c_mic_process_exit_sig,
msg_c_mic_process_exit,
msg_c_mic_init3,
msg_c_mic_init4,
msg_c_mic_init5,
msg_c_mic_init6,
msg_c_no_static_var_data,
msg_c_no_ptr_data,
msg_c_get_engine_handle,
msg_c_get_engine_index,
msg_c_process_create,
msg_c_process_get_func_handles,
msg_c_process_wait_shutdown,
msg_c_process_proxy_flush,
msg_c_load_library,
msg_c_pipeline_create,
msg_c_pipeline_run_func,
msg_c_pipeline_start_run_funcs,
msg_c_buf_create,
msg_c_buf_create_out_of_mem,
msg_c_buf_create_from_mem,
msg_c_buf_destroy,
msg_c_buf_map,
msg_c_buf_unmap,
msg_c_buf_read,
msg_c_buf_write,
msg_c_buf_copy,
msg_c_buf_get_address,
msg_c_buf_add_ref,
msg_c_buf_release_ref,
msg_c_buf_set_state,
msg_c_event_wait,
msg_c_zero_or_neg_ptr_len,
msg_c_zero_or_neg_transfer_size,
msg_c_bad_ptr_mem_range,
msg_c_different_src_and_dstn_sizes,
msg_c_non_contiguous_dope_vector,
msg_c_omp_invalid_device_num_env,
msg_c_omp_invalid_device_num,
msg_c_unknown_binary_type,
msg_c_multiple_target_exes,
msg_c_no_target_exe,
msg_c_report_unknown_timer_node,
msg_c_report_unknown_trace_node,
msg_c_report_host,
msg_c_report_mic,
msg_c_report_title,
msg_c_report_seconds,
msg_c_report_bytes,
msg_c_report_cpu_time,
msg_c_report_mic_time,
msg_c_report_tag,
msg_c_report_from_file,
msg_c_report_file,
msg_c_report_line,
msg_c_report_cpu_to_mic_data,
msg_c_report_mic_to_cpu_data,
msg_c_report_offload,
msg_c_report_w_tag,
msg_c_report_state,
msg_c_report_start,
msg_c_report_init,
msg_c_report_logical_card,
msg_c_report_physical_card,
msg_c_report_register,
msg_c_report_init_func,
msg_c_report_create_buf_host,
msg_c_report_create_buf_mic,
msg_c_report_send_pointer_data,
msg_c_report_sent_pointer_data,
msg_c_report_gather_copyin_data,
msg_c_report_copyin_data,
msg_c_report_state_signal,
msg_c_report_signal,
msg_c_report_wait,
msg_c_report_compute,
msg_c_report_receive_pointer_data,
msg_c_report_received_pointer_data,
msg_c_report_start_target_func,
msg_c_report_var,
msg_c_report_scatter_copyin_data,
msg_c_report_gather_copyout_data,
msg_c_report_scatter_copyout_data,
msg_c_report_copyout_data,
msg_c_report_unregister,
msg_c_report_destroy,
msg_c_report_myoinit,
msg_c_report_myoregister,
msg_c_report_myofini,
msg_c_report_mic_myo_shared,
msg_c_report_mic_myo_fptr,
msg_c_report_myosharedmalloc,
msg_c_report_myosharedfree,
msg_c_report_myosharedalignedmalloc,
msg_c_report_myosharedalignedfree,
msg_c_report_myoacquire,
msg_c_report_myorelease,
msg_c_report_host_total_offload_time,
msg_c_report_host_initialize,
msg_c_report_host_target_acquire,
msg_c_report_host_wait_deps,
msg_c_report_host_setup_buffers,
msg_c_report_host_alloc_buffers,
msg_c_report_host_setup_misc_data,
msg_c_report_host_alloc_data_buffer,
msg_c_report_host_send_pointers,
msg_c_report_host_gather_inputs,
msg_c_report_host_map_in_data_buffer,
msg_c_report_host_unmap_in_data_buffer,
msg_c_report_host_start_compute,
msg_c_report_host_wait_compute,
msg_c_report_host_start_buffers_reads,
msg_c_report_host_scatter_outputs,
msg_c_report_host_map_out_data_buffer,
msg_c_report_host_unmap_out_data_buffer,
msg_c_report_host_wait_buffers_reads,
msg_c_report_host_destroy_buffers,
msg_c_report_target_total_time,
msg_c_report_target_descriptor_setup,
msg_c_report_target_func_lookup,
msg_c_report_target_func_time,
msg_c_report_target_scatter_inputs,
msg_c_report_target_add_buffer_refs,
msg_c_report_target_compute,
msg_c_report_target_gather_outputs,
msg_c_report_target_release_buffer_refs,
msg_c_coi_pipeline_max_number,
msg_c_ranges_dont_match,
msg_c_destination_is_over,
msg_c_slice_of_noncont_array,
msg_c_pointer_array_mismatch,
lastMsg = 152,
firstMsg = 1
};
#if !defined(MESSAGE_TABLE_NAME)
# define MESSAGE_TABLE_NAME __liboffload_message_table
#endif
static char const * MESSAGE_TABLE_NAME[] = {
/* 0 __dummy__ */ "Un-used message",
/* 1 msg_c_device_is_not_available */ "offload error: cannot offload to MIC - device is not available",
/* 2 msg_c_invalid_device_number */ "offload error: expected a number greater than or equal to -1",
/* 3 msg_c_send_func_ptr */ "offload error: cannot find function name for address %p",
/* 4 msg_c_receive_func_ptr */ "offload error: cannot find address of function %s",
/* 5 msg_c_offload_malloc */ "offload error: memory allocation failed (requested=%lld bytes, align %lld)",
/* 6 msg_c_offload1 */ "offload error: device %d does not have a pending signal for wait(%p)",
/* 7 msg_c_unknown_var_type */ "offload error: unknown variable type %d",
/* 8 msg_c_invalid_env_var_value */ "offload warning: ignoring invalid value specified for %s",
/* 9 msg_c_invalid_env_var_int_value */ "offload warning: specify an integer value for %s",
/* 10 msg_c_invalid_env_report_value */ "offload warning: ignoring %s setting; use a value in range 1-3",
/* 11 msg_c_offload_signaled1 */ "offload error: invalid device number %d specified in _Offload_signaled",
/* 12 msg_c_offload_signaled2 */ "offload error: invalid signal %p specified for _Offload_signaled",
/* 13 msg_c_myowrapper_checkresult */ "offload error: %s failed with error %d",
/* 14 msg_c_myotarget_checkresult */ "offload error: %s failed with error %d",
/* 15 msg_c_offload_descriptor_offload */ "offload error: cannot find offload entry %s",
/* 16 msg_c_merge_var_descs1 */ "offload error: unexpected number of variable descriptors",
/* 17 msg_c_merge_var_descs2 */ "offload error: unexpected variable type",
/* 18 msg_c_mic_parse_env_var_list1 */ "offload_error: MIC environment variable must begin with an alpabetic character",
/* 19 msg_c_mic_parse_env_var_list2 */ "offload_error: MIC environment variable value must be specified with <20>=<3D>",
/* 20 msg_c_mic_process_exit_ret */ "offload error: process on the device %d unexpectedly exited with code %d",
/* 21 msg_c_mic_process_exit_sig */ "offload error: process on the device %d was terminated by signal %d (%s)",
/* 22 msg_c_mic_process_exit */ "offload error: process on the device %d was unexpectedly terminated",
/* 23 msg_c_mic_init3 */ "offload warning: ignoring MIC_STACKSIZE setting; use a value >= 16K and a multiple of 4K",
/* 24 msg_c_mic_init4 */ "offload error: thread key create failed with error %d",
/* 25 msg_c_mic_init5 */ "offload warning: specify OFFLOAD_DEVICES as comma-separated physical device numbers or 'none'",
/* 26 msg_c_mic_init6 */ "offload warning: OFFLOAD_DEVICES device number %d does not correspond to a physical device",
/* 27 msg_c_no_static_var_data */ "offload error: cannot find data associated with statically allocated variable %p",
/* 28 msg_c_no_ptr_data */ "offload error: cannot find data associated with pointer variable %p",
/* 29 msg_c_get_engine_handle */ "offload error: cannot get device %d handle (error code %d)",
/* 30 msg_c_get_engine_index */ "offload error: cannot get physical index for logical device %d (error code %d)",
/* 31 msg_c_process_create */ "offload error: cannot start process on the device %d (error code %d)",
/* 32 msg_c_process_get_func_handles */ "offload error: cannot get function handles on the device %d (error code %d)",
/* 33 msg_c_process_wait_shutdown */ "offload error: wait for process shutdown failed on device %d (error code %d)",
/* 34 msg_c_process_proxy_flush */ "offload error: cannot flush process output on device %d (error code %d)",
/* 35 msg_c_load_library */ "offload error: cannot load library to the device %d (error code %d)",
/* 36 msg_c_pipeline_create */ "offload error: cannot create pipeline on the device %d (error code %d)",
/* 37 msg_c_pipeline_run_func */ "offload error: cannot execute function on the device %d (error code %d)",
/* 38 msg_c_pipeline_start_run_funcs */ "offload error: cannot start executing pipeline function on the device %d (error code %d)",
/* 39 msg_c_buf_create */ "offload error: cannot create buffer on device %d (error code %d)",
/* 40 msg_c_buf_create_out_of_mem */ "offload error: cannot create buffer on device %d, out of memory",
/* 41 msg_c_buf_create_from_mem */ "offload error: cannot create buffer from memory on device %d (error code %d)",
/* 42 msg_c_buf_destroy */ "offload error: buffer destroy failed (error code %d)",
/* 43 msg_c_buf_map */ "offload error: buffer map failed (error code %d)",
/* 44 msg_c_buf_unmap */ "offload error: buffer unmap failed (error code %d)",
/* 45 msg_c_buf_read */ "offload error: buffer read failed (error code %d)",
/* 46 msg_c_buf_write */ "offload error: buffer write failed (error code %d)",
/* 47 msg_c_buf_copy */ "offload error: buffer copy failed (error code %d)",
/* 48 msg_c_buf_get_address */ "offload error: cannot get buffer address on device %d (error code %d)",
/* 49 msg_c_buf_add_ref */ "offload error: cannot reuse buffer memory on device %d (error code %d)",
/* 50 msg_c_buf_release_ref */ "offload error: cannot release buffer memory on device %d (error code %d)",
/* 51 msg_c_buf_set_state */ "offload error: buffer set state failed (error code %d)",
/* 52 msg_c_event_wait */ "offload error: wait for event to become signaled failed (error code %d)",
/* 53 msg_c_zero_or_neg_ptr_len */ "offload error: memory allocation of negative length is not supported",
/* 54 msg_c_zero_or_neg_transfer_size */ "offload error: data transfer of zero or negative size is not supported",
/* 55 msg_c_bad_ptr_mem_range */ "offload error: address range partially overlaps with existing allocation",
/* 56 msg_c_different_src_and_dstn_sizes */ "offload error: size of the source %d differs from size of the destination %d",
/* 57 msg_c_non_contiguous_dope_vector */ "offload error: offload data transfer supports only a single contiguous memory range per variable",
/* 58 msg_c_omp_invalid_device_num_env */ "offload warning: ignoring %s setting; use a non-negative integer value",
/* 59 msg_c_omp_invalid_device_num */ "offload error: device number should be a non-negative integer value",
/* 60 msg_c_unknown_binary_type */ "offload error: unexpected embedded target binary type, expected either an executable or shared library",
/* 61 msg_c_multiple_target_exes */ "offload error: more that one target executable found",
/* 62 msg_c_no_target_exe */ "offload error: target executable is not available",
/* 63 msg_c_report_unknown_timer_node */ "offload error: unknown timer node",
/* 64 msg_c_report_unknown_trace_node */ "offload error: unknown trace node",
/* 65 msg_c_report_host */ "HOST",
/* 66 msg_c_report_mic */ "MIC",
/* 67 msg_c_report_title */ "timer data (sec)",
/* 68 msg_c_report_seconds */ "(seconds)",
/* 69 msg_c_report_bytes */ "(bytes)",
/* 70 msg_c_report_cpu_time */ "CPU Time",
/* 71 msg_c_report_mic_time */ "MIC Time",
/* 72 msg_c_report_tag */ "Tag",
/* 73 msg_c_report_from_file */ "Offload from file",
/* 74 msg_c_report_file */ "File",
/* 75 msg_c_report_line */ "Line",
/* 76 msg_c_report_cpu_to_mic_data */ "CPU->MIC Data",
/* 77 msg_c_report_mic_to_cpu_data */ "MIC->CPU Data",
/* 78 msg_c_report_offload */ "Offload",
/* 79 msg_c_report_w_tag */ "Tag %d",
/* 80 msg_c_report_state */ "State",
/* 81 msg_c_report_start */ "Start target",
/* 82 msg_c_report_init */ "Initialize",
/* 83 msg_c_report_logical_card */ "logical card",
/* 84 msg_c_report_physical_card */ "physical card",
/* 85 msg_c_report_register */ "Register static data tables",
/* 86 msg_c_report_init_func */ "Setup target entry",
/* 87 msg_c_report_create_buf_host */ "Create host buffer",
/* 88 msg_c_report_create_buf_mic */ "Create target buffer",
/* 89 msg_c_report_send_pointer_data */ "Send pointer data",
/* 90 msg_c_report_sent_pointer_data */ "Host->target pointer data",
/* 91 msg_c_report_gather_copyin_data */ "Gather copyin data",
/* 92 msg_c_report_copyin_data */ "Host->target copyin data",
/* 93 msg_c_report_state_signal */ "Signal",
/* 94 msg_c_report_signal */ "signal :",
/* 95 msg_c_report_wait */ "waits :",
/* 96 msg_c_report_compute */ "Execute task on target",
/* 97 msg_c_report_receive_pointer_data */ "Receive pointer data",
/* 98 msg_c_report_received_pointer_data */ "Target->host pointer data",
/* 99 msg_c_report_start_target_func */ "Start target entry",
/* 100 msg_c_report_var */ "Var",
/* 101 msg_c_report_scatter_copyin_data */ "Scatter copyin data",
/* 102 msg_c_report_gather_copyout_data */ "Gather copyout data",
/* 103 msg_c_report_scatter_copyout_data */ "Scatter copyout data",
/* 104 msg_c_report_copyout_data */ "Target->host copyout data",
/* 105 msg_c_report_unregister */ "Unregister data tables",
/* 106 msg_c_report_destroy */ "Destroy",
/* 107 msg_c_report_myoinit */ "Initialize MYO",
/* 108 msg_c_report_myoregister */ "Register MYO tables",
/* 109 msg_c_report_myofini */ "Finalize MYO",
/* 110 msg_c_report_mic_myo_shared */ "MIC MYO shared table register",
/* 111 msg_c_report_mic_myo_fptr */ "MIC MYO fptr table register",
/* 112 msg_c_report_myosharedmalloc */ "MYO shared malloc",
/* 113 msg_c_report_myosharedfree */ "MYO shared free",
/* 114 msg_c_report_myosharedalignedmalloc */ "MYO shared aligned malloc",
/* 115 msg_c_report_myosharedalignedfree */ "MYO shared aligned free",
/* 116 msg_c_report_myoacquire */ "MYO acquire",
/* 117 msg_c_report_myorelease */ "MYO release",
/* 118 msg_c_report_host_total_offload_time */ "host: total offload time",
/* 119 msg_c_report_host_initialize */ "host: initialize target",
/* 120 msg_c_report_host_target_acquire */ "host: acquire target",
/* 121 msg_c_report_host_wait_deps */ "host: wait dependencies",
/* 122 msg_c_report_host_setup_buffers */ "host: setup buffers",
/* 123 msg_c_report_host_alloc_buffers */ "host: allocate buffers",
/* 124 msg_c_report_host_setup_misc_data */ "host: setup misc_data",
/* 125 msg_c_report_host_alloc_data_buffer */ "host: allocate buffer",
/* 126 msg_c_report_host_send_pointers */ "host: send pointers",
/* 127 msg_c_report_host_gather_inputs */ "host: gather inputs",
/* 128 msg_c_report_host_map_in_data_buffer */ "host: map IN data buffer",
/* 129 msg_c_report_host_unmap_in_data_buffer */ "host: unmap IN data buffer",
/* 130 msg_c_report_host_start_compute */ "host: initiate compute",
/* 131 msg_c_report_host_wait_compute */ "host: wait compute",
/* 132 msg_c_report_host_start_buffers_reads */ "host: initiate pointer reads",
/* 133 msg_c_report_host_scatter_outputs */ "host: scatter outputs",
/* 134 msg_c_report_host_map_out_data_buffer */ "host: map OUT data buffer",
/* 135 msg_c_report_host_unmap_out_data_buffer */ "host: unmap OUT data buffer",
/* 136 msg_c_report_host_wait_buffers_reads */ "host: wait pointer reads",
/* 137 msg_c_report_host_destroy_buffers */ "host: destroy buffers",
/* 138 msg_c_report_target_total_time */ "target: total time",
/* 139 msg_c_report_target_descriptor_setup */ "target: setup offload descriptor",
/* 140 msg_c_report_target_func_lookup */ "target: entry lookup",
/* 141 msg_c_report_target_func_time */ "target: entry time",
/* 142 msg_c_report_target_scatter_inputs */ "target: scatter inputs",
/* 143 msg_c_report_target_add_buffer_refs */ "target: add buffer reference",
/* 144 msg_c_report_target_compute */ "target: compute",
/* 145 msg_c_report_target_gather_outputs */ "target: gather outputs",
/* 146 msg_c_report_target_release_buffer_refs */ "target: remove buffer reference",
/* 147 msg_c_coi_pipeline_max_number */ "number of host threads doing offload exceeds maximum of %d",
/* 148 msg_c_ranges_dont_match */ "ranges of source and destination don't match together",
/* 149 msg_c_destination_is_over */ "insufficient destination memory to transfer source",
/* 150 msg_c_slice_of_noncont_array */ "a non-contiguous slice may be taken of contiguous arrays only",
/* 151 msg_c_pointer_array_mismatch */ "number of %s elements is less than described by the source",
};

View File

@@ -0,0 +1,441 @@
!
!//===----------------------------------------------------------------------===//
!//
!// The LLVM Compiler Infrastructure
!//
!// This file is dual licensed under the MIT and the University of Illinois Open
!// Source Licenses. See LICENSE.txt for details.
!//
!//===----------------------------------------------------------------------===//
!
! **********************************************************************************
! * This file is intended to support the Intel(r) Many Integrated Core Architecture.
! **********************************************************************************
! free form Fortran source - should be named .f90
! lines are longer than 72 characters
module mic_lib
use, intrinsic :: iso_c_binding
integer, parameter:: target_mic=2
integer, parameter:: default_target_type=target_mic
integer, parameter:: default_target_number=0
enum, bind(C)
enumerator :: OFFLOAD_SUCCESS = 0
enumerator :: OFFLOAD_DISABLED ! offload is disabled
enumerator :: OFFLOAD_UNAVAILABLE ! card is not available
enumerator :: OFFLOAD_OUT_OF_MEMORY ! not enough memory on device
enumerator :: OFFLOAD_PROCESS_DIED ! target process has died
enumerator :: OFFLOAD_ERROR ! unspecified error
end enum
type, bind (C) :: offload_status
integer(kind=c_int) :: result = OFFLOAD_DISABLED
integer(kind=c_int) :: device_number = -1
integer(kind=c_size_t) :: data_sent = 0
integer(kind=c_size_t) :: data_received = 0
end type offload_status
interface
function offload_number_of_devices () &
bind (C, name = "_Offload_number_of_devices")
!dec$ attributes default :: offload_number_of_devices
import :: c_int
integer (kind=c_int) :: offload_number_of_devices
!dec$ attributes offload:mic :: offload_number_of_devices
!dir$ attributes known_intrinsic :: offload_number_of_devices
end function offload_number_of_devices
function offload_signaled(target_number, signal) &
bind (C, name = "_Offload_signaled")
!dec$ attributes default :: offload_signaled
import :: c_int, c_int64_t
integer (kind=c_int) :: offload_signaled
integer (kind=c_int), value :: target_number
integer (kind=c_int64_t), value :: signal
!dec$ attributes offload:mic :: offload_signaled
end function offload_signaled
subroutine offload_report(val) &
bind (C, name = "_Offload_report")
!dec$ attributes default :: offload_report
import :: c_int
integer (kind=c_int), value :: val
!dec$ attributes offload:mic :: offload_report
end subroutine offload_report
function offload_get_device_number() &
bind (C, name = "_Offload_get_device_number")
!dec$ attributes default :: offload_get_device_number
import :: c_int
integer (kind=c_int) :: offload_get_device_number
!dec$ attributes offload:mic :: offload_get_device_number
end function offload_get_device_number
function offload_get_physical_device_number() &
bind (C, name = "_Offload_get_physical_device_number")
!dec$ attributes default :: offload_get_physical_device_number
import :: c_int
integer (kind=c_int) :: offload_get_physical_device_number
!dec$ attributes offload:mic :: offload_get_physical_device_number
end function offload_get_physical_device_number
! OpenMP API wrappers
subroutine omp_set_num_threads_target (target_type, &
target_number, &
num_threads) &
bind (C, name = "omp_set_num_threads_target")
import :: c_int
integer (kind=c_int), value :: target_type, target_number, num_threads
end subroutine omp_set_num_threads_target
function omp_get_max_threads_target (target_type, &
target_number) &
bind (C, name = "omp_get_max_threads_target")
import :: c_int
integer (kind=c_int) :: omp_get_max_threads_target
integer (kind=c_int), value :: target_type, target_number
end function omp_get_max_threads_target
function omp_get_num_procs_target (target_type, &
target_number) &
bind (C, name = "omp_get_num_procs_target")
import :: c_int
integer (kind=c_int) :: omp_get_num_procs_target
integer (kind=c_int), value :: target_type, target_number
end function omp_get_num_procs_target
subroutine omp_set_dynamic_target (target_type, &
target_number, &
num_threads) &
bind (C, name = "omp_set_dynamic_target")
import :: c_int
integer (kind=c_int), value :: target_type, target_number, num_threads
end subroutine omp_set_dynamic_target
function omp_get_dynamic_target (target_type, &
target_number) &
bind (C, name = "omp_get_dynamic_target")
import :: c_int
integer (kind=c_int) :: omp_get_dynamic_target
integer (kind=c_int), value :: target_type, target_number
end function omp_get_dynamic_target
subroutine omp_set_nested_target (target_type, &
target_number, &
nested) &
bind (C, name = "omp_set_nested_target")
import :: c_int
integer (kind=c_int), value :: target_type, target_number, nested
end subroutine omp_set_nested_target
function omp_get_nested_target (target_type, &
target_number) &
bind (C, name = "omp_get_nested_target")
import :: c_int
integer (kind=c_int) :: omp_get_nested_target
integer (kind=c_int), value :: target_type, target_number
end function omp_get_nested_target
subroutine omp_set_schedule_target (target_type, &
target_number, &
kind, &
modifier) &
bind (C, name = "omp_set_schedule_target")
import :: c_int
integer (kind=c_int), value :: target_type, target_number, kind, modifier
end subroutine omp_set_schedule_target
subroutine omp_get_schedule_target (target_type, &
target_number, &
kind, &
modifier) &
bind (C, name = "omp_get_schedule_target")
import :: c_int, c_intptr_t
integer (kind=c_int), value :: target_type, target_number
integer (kind=c_intptr_t), value :: kind, modifier
end subroutine omp_get_schedule_target
! lock API functions
subroutine omp_init_lock_target (target_type, &
target_number, &
lock) &
bind (C, name = "omp_init_lock_target")
import :: c_int, c_intptr_t
!dir$ attributes known_intrinsic :: omp_init_lock_target
integer (kind=c_int), value :: target_type, target_number
integer (kind=c_intptr_t), value :: lock
end subroutine omp_init_lock_target
subroutine omp_destroy_lock_target (target_type, &
target_number, &
lock) &
bind (C, name = "omp_destroy_lock_target")
import :: c_int, c_intptr_t
!dir$ attributes known_intrinsic :: omp_destroy_lock_target
integer (kind=c_int), value :: target_type, target_number
integer (kind=c_intptr_t), value :: lock
end subroutine omp_destroy_lock_target
subroutine omp_set_lock_target (target_type, &
target_number, &
lock) &
bind (C, name = "omp_set_lock_target")
import :: c_int, c_intptr_t
!dir$ attributes known_intrinsic :: omp_set_lock_target
integer (kind=c_int), value :: target_type, target_number
integer (kind=c_intptr_t), value :: lock
end subroutine omp_set_lock_target
subroutine omp_unset_lock_target (target_type, &
target_number, &
lock) &
bind (C, name = "omp_unset_lock_target")
import :: c_int, c_intptr_t
!dir$ attributes known_intrinsic :: omp_unset_lock_target
integer (kind=c_int), value :: target_type, target_number
integer (kind=c_intptr_t), value :: lock
end subroutine omp_unset_lock_target
function omp_test_lock_target (target_type, &
target_number, &
lock) &
bind (C, name = "omp_test_lock_target")
import :: c_int, c_intptr_t
integer (kind=c_int) :: omp_test_lock_target
integer (kind=c_int), value :: target_type, target_number
integer (kind=c_intptr_t), value :: lock
end function omp_test_lock_target
! nested lock API functions
subroutine omp_init_nest_lock_target (target_type, &
target_number, &
lock) &
bind (C, name = "omp_init_nest_lock_target")
import :: c_int, c_intptr_t
integer (kind=c_int), value :: target_type, target_number
integer (kind=c_intptr_t), value :: lock
end subroutine omp_init_nest_lock_target
subroutine omp_destroy_nest_lock_target (target_type, &
target_number, &
lock) &
bind (C, name = "omp_destroy_nest_lock_target")
import :: c_int, c_intptr_t
integer (kind=c_int), value :: target_type, target_number
integer (kind=c_intptr_t), value :: lock
end subroutine omp_destroy_nest_lock_target
subroutine omp_set_nest_lock_target (target_type, &
target_number, &
lock) &
bind (C, name = "omp_set_nest_lock_target")
import :: c_int, c_intptr_t
integer (kind=c_int), value :: target_type, target_number
integer (kind=c_intptr_t), value :: lock
end subroutine omp_set_nest_lock_target
subroutine omp_unset_nest_lock_target (target_type, &
target_number, &
lock) &
bind (C, name = "omp_unset_nest_lock_target")
import :: c_int, c_intptr_t
integer (kind=c_int), value :: target_type, target_number
integer (kind=c_intptr_t), value :: lock
end subroutine omp_unset_nest_lock_target
function omp_test_nest_lock_target (target_type, &
target_number, &
lock) &
bind (C, name = "omp_test_nest_lock_target")
import :: c_int, c_intptr_t
integer (kind=c_int) :: omp_test_nest_lock_target
integer (kind=c_int), value :: target_type, target_number
integer (kind=c_intptr_t), value :: lock
end function omp_test_nest_lock_target
! kmp API functions
subroutine kmp_set_stacksize_target (target_type, &
target_number, &
size) &
bind (C, name = "kmp_set_stacksize_target")
import :: c_int
integer (kind=c_int), value :: target_type, target_number, size
end subroutine kmp_set_stacksize_target
function kmp_get_stacksize_target (target_type, &
target_number) &
bind (C, name = "kmp_get_stacksize_target")
import :: c_int
integer (kind=c_int) :: kmp_get_stacksize_target
integer (kind=c_int), value :: target_type, target_number
end function kmp_get_stacksize_target
subroutine kmp_set_stacksize_s_target (target_type, &
target_number, &
size) &
bind (C, name = "kmp_set_stacksize_s_target")
import :: c_int
integer (kind=c_int), value :: target_type, target_number, size
end subroutine kmp_set_stacksize_s_target
function kmp_get_stacksize_s_target (target_type, &
target_number) &
bind (C, name = "kmp_get_stacksize_s_target")
import :: c_int
integer (kind=c_int) :: kmp_get_stacksize_s_target
integer (kind=c_int), value :: target_type, target_number
end function kmp_get_stacksize_s_target
subroutine kmp_set_blocktime_target (target_type, &
target_number, &
time) &
bind (C, name = "kmp_set_blocktime_target")
import :: c_int
integer (kind=c_int), value :: target_type, target_number, time
end subroutine kmp_set_blocktime_target
function kmp_get_blocktime_target (target_type, &
target_number) &
bind (C, name = "kmp_get_blocktime_target")
import :: c_int
integer (kind=c_int) :: kmp_get_blocktime_target
integer (kind=c_int), value :: target_type, target_number
end function kmp_get_blocktime_target
subroutine kmp_set_library_serial_target (target_type, &
target_number) &
bind (C, name = "kmp_set_library_serial_target")
import :: c_int
integer (kind=c_int), value :: target_type, target_number
end subroutine kmp_set_library_serial_target
subroutine kmp_set_library_turnaround_target (target_type, &
target_number) &
bind (C, name = "kmp_set_library_turnaround_target")
import :: c_int
integer (kind=c_int), value :: target_type, target_number
end subroutine kmp_set_library_turnaround_target
subroutine kmp_set_library_throughput_target (target_type, &
target_number) &
bind (C, name = "kmp_set_library_throughput_target")
import :: c_int
integer (kind=c_int), value :: target_type, target_number
end subroutine kmp_set_library_throughput_target
subroutine kmp_set_library_target (target_type, &
target_number, &
mode) &
bind (C, name = "kmp_set_library_target")
import :: c_int
integer (kind=c_int), value :: target_type, target_number, mode
end subroutine kmp_set_library_target
function kmp_get_library_target (target_type, &
target_number) &
bind (C, name = "kmp_get_library_target")
import :: c_int
integer (kind=c_int) :: kmp_get_library_target
integer (kind=c_int), value :: target_type, target_number
end function kmp_get_library_target
subroutine kmp_set_defaults_target (target_type, &
target_number, &
defaults) &
bind (C, name = "kmp_set_defaults_target")
import :: c_int, c_char
character (kind=c_char) :: defaults(*)
integer (kind=c_int), value :: target_type, target_number
end subroutine kmp_set_defaults_target
! affinity API functions
subroutine kmp_create_affinity_mask_target (target_type, &
target_number, &
mask) &
bind (C, name = "kmp_create_affinity_mask_target")
import :: c_int, c_intptr_t
integer (kind=c_int), value :: target_type, target_number
integer (kind=c_intptr_t), value :: mask
end subroutine kmp_create_affinity_mask_target
subroutine kmp_destroy_affinity_mask_target (target_type, &
target_number, &
mask) &
bind (C, name = "kmp_destroy_affinity_mask_target")
import :: c_int, c_intptr_t
integer (kind=c_int), value :: target_type, target_number
integer (kind=c_intptr_t), value :: mask
end subroutine kmp_destroy_affinity_mask_target
function kmp_set_affinity_target (target_type, &
target_number, &
mask) &
bind (C, name = "kmp_set_affinity_target")
import :: c_int, c_intptr_t
integer (kind=c_int) :: kmp_set_affinity_target
integer (kind=c_int), value :: target_type, target_number
integer (kind=c_intptr_t), value :: mask
end function kmp_set_affinity_target
function kmp_get_affinity_target (target_type, &
target_number, &
mask) &
bind (C, name = "kmp_get_affinity_target")
import :: c_int, c_intptr_t
integer (kind=c_int) :: kmp_get_affinity_target
integer (kind=c_int), value :: target_type, target_number
integer (kind=c_intptr_t), value :: mask
end function kmp_get_affinity_target
function kmp_get_affinity_max_proc_target (target_type, &
target_number) &
bind (C, name = "kmp_get_affinity_max_proc_target")
import :: c_int
integer (kind=c_int) :: kmp_get_affinity_max_proc_target
integer (kind=c_int), value :: target_type, target_number
end function kmp_get_affinity_max_proc_target
function kmp_set_affinity_mask_proc_target (target_type, &
target_number, &
proc, &
mask) &
bind (C, name = "kmp_set_affinity_mask_proc_target")
import :: c_int, c_intptr_t
integer (kind=c_int) :: kmp_set_affinity_mask_proc_target
integer (kind=c_int), value :: target_type, target_number, proc
integer (kind=c_intptr_t), value :: mask
end function kmp_set_affinity_mask_proc_target
function kmp_unset_affinity_mask_proc_target (target_type, &
target_number, &
proc, &
mask) &
bind (C, name = "kmp_unset_affinity_mask_proc_target")
import :: c_int, c_intptr_t
integer (kind=c_int) :: kmp_unset_affinity_mask_proc_target
integer (kind=c_int), value :: target_type, target_number, proc
integer (kind=c_intptr_t), value :: mask
end function kmp_unset_affinity_mask_proc_target
function kmp_get_affinity_mask_proc_target (target_type, &
target_number, &
proc, &
mask) &
bind (C, name = "kmp_get_affinity_mask_proc_target")
import :: c_int, c_intptr_t
integer (kind=c_int) :: kmp_get_affinity_mask_proc_target
integer (kind=c_int), value :: target_type, target_number, proc
integer (kind=c_intptr_t), value :: mask
end function kmp_get_affinity_mask_proc_target
end interface
end module mic_lib

View File

@@ -0,0 +1,474 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
/*
* Include file for Offload API.
*/
#ifndef OFFLOAD_H_INCLUDED
#define OFFLOAD_H_INCLUDED
#if defined(LINUX) || defined(FREEBSD)
#include <bits/functexcept.h>
#endif
#include <stddef.h>
#include <omp.h>
#ifdef __cplusplus
extern "C" {
#endif
#define TARGET_ATTRIBUTE __declspec(target(mic))
/*
* The target architecture.
*/
typedef enum TARGET_TYPE {
TARGET_NONE, /* Undefine target */
TARGET_HOST, /* Host used as target */
TARGET_MIC /* MIC target */
} TARGET_TYPE;
/*
* The default target type.
*/
#define DEFAULT_TARGET_TYPE TARGET_MIC
/*
* The default target number.
*/
#define DEFAULT_TARGET_NUMBER 0
/*
* Offload status.
*/
typedef enum {
OFFLOAD_SUCCESS = 0,
OFFLOAD_DISABLED, /* offload is disabled */
OFFLOAD_UNAVAILABLE, /* card is not available */
OFFLOAD_OUT_OF_MEMORY, /* not enough memory on device */
OFFLOAD_PROCESS_DIED, /* target process has died */
OFFLOAD_ERROR /* unspecified error */
} _Offload_result;
typedef struct {
_Offload_result result; /* result, see above */
int device_number; /* device number */
size_t data_sent; /* number of bytes sent to the target */
size_t data_received; /* number of bytes received by host */
} _Offload_status;
#define OFFLOAD_STATUS_INIT(x) \
((x).result = OFFLOAD_DISABLED)
#define OFFLOAD_STATUS_INITIALIZER \
{ OFFLOAD_DISABLED, -1, 0, 0 }
/* Offload runtime interfaces */
extern int _Offload_number_of_devices(void);
extern int _Offload_get_device_number(void);
extern int _Offload_get_physical_device_number(void);
extern void* _Offload_shared_malloc(size_t size);
extern void _Offload_shared_free(void *ptr);
extern void* _Offload_shared_aligned_malloc(size_t size, size_t align);
extern void _Offload_shared_aligned_free(void *ptr);
extern int _Offload_signaled(int index, void *signal);
extern void _Offload_report(int val);
/* OpenMP API */
extern void omp_set_default_device(int num);
extern int omp_get_default_device(void);
extern int omp_get_num_devices(void);
/* OpenMP API wrappers */
/* Set num_threads on target */
extern void omp_set_num_threads_target(
TARGET_TYPE target_type,
int target_number,
int num_threads
);
/* Get max_threads from target */
extern int omp_get_max_threads_target(
TARGET_TYPE target_type,
int target_number
);
/* Get num_procs from target */
extern int omp_get_num_procs_target(
TARGET_TYPE target_type,
int target_number
);
/* Set dynamic on target */
extern void omp_set_dynamic_target(
TARGET_TYPE target_type,
int target_number,
int num_threads
);
/* Get dynamic from target */
extern int omp_get_dynamic_target(
TARGET_TYPE target_type,
int target_number
);
/* Set nested on target */
extern void omp_set_nested_target(
TARGET_TYPE target_type,
int target_number,
int nested
);
/* Get nested from target */
extern int omp_get_nested_target(
TARGET_TYPE target_type,
int target_number
);
extern void omp_set_num_threads_target(
TARGET_TYPE target_type,
int target_number,
int num_threads
);
extern int omp_get_max_threads_target(
TARGET_TYPE target_type,
int target_number
);
extern int omp_get_num_procs_target(
TARGET_TYPE target_type,
int target_number
);
extern void omp_set_dynamic_target(
TARGET_TYPE target_type,
int target_number,
int num_threads
);
extern int omp_get_dynamic_target(
TARGET_TYPE target_type,
int target_number
);
extern void omp_set_nested_target(
TARGET_TYPE target_type,
int target_number,
int num_threads
);
extern int omp_get_nested_target(
TARGET_TYPE target_type,
int target_number
);
extern void omp_set_schedule_target(
TARGET_TYPE target_type,
int target_number,
omp_sched_t kind,
int modifier
);
extern void omp_get_schedule_target(
TARGET_TYPE target_type,
int target_number,
omp_sched_t *kind,
int *modifier
);
/* lock API functions */
typedef struct {
omp_lock_t lock;
} omp_lock_target_t;
extern void omp_init_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_lock_target_t *lock
);
extern void omp_destroy_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_lock_target_t *lock
);
extern void omp_set_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_lock_target_t *lock
);
extern void omp_unset_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_lock_target_t *lock
);
extern int omp_test_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_lock_target_t *lock
);
/* nested lock API functions */
typedef struct {
omp_nest_lock_t lock;
} omp_nest_lock_target_t;
extern void omp_init_nest_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_nest_lock_target_t *lock
);
extern void omp_destroy_nest_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_nest_lock_target_t *lock
);
extern void omp_set_nest_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_nest_lock_target_t *lock
);
extern void omp_unset_nest_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_nest_lock_target_t *lock
);
extern int omp_test_nest_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_nest_lock_target_t *lock
);
/* kmp API functions */
extern void kmp_set_stacksize_target(
TARGET_TYPE target_type,
int target_number,
int size
);
extern int kmp_get_stacksize_target(
TARGET_TYPE target_type,
int target_number
);
extern void kmp_set_stacksize_s_target(
TARGET_TYPE target_type,
int target_number,
size_t size
);
extern size_t kmp_get_stacksize_s_target(
TARGET_TYPE target_type,
int target_number
);
extern void kmp_set_blocktime_target(
TARGET_TYPE target_type,
int target_number,
int time
);
extern int kmp_get_blocktime_target(
TARGET_TYPE target_type,
int target_number
);
extern void kmp_set_library_serial_target(
TARGET_TYPE target_type,
int target_number
);
extern void kmp_set_library_turnaround_target(
TARGET_TYPE target_type,
int target_number
);
extern void kmp_set_library_throughput_target(
TARGET_TYPE target_type,
int target_number
);
extern void kmp_set_library_target(
TARGET_TYPE target_type,
int target_number,
int mode
);
extern int kmp_get_library_target(
TARGET_TYPE target_type,
int target_number
);
extern void kmp_set_defaults_target(
TARGET_TYPE target_type,
int target_number,
char const *defaults
);
/* affinity API functions */
typedef struct {
kmp_affinity_mask_t mask;
} kmp_affinity_mask_target_t;
extern void kmp_create_affinity_mask_target(
TARGET_TYPE target_type,
int target_number,
kmp_affinity_mask_target_t *mask
);
extern void kmp_destroy_affinity_mask_target(
TARGET_TYPE target_type,
int target_number,
kmp_affinity_mask_target_t *mask
);
extern int kmp_set_affinity_target(
TARGET_TYPE target_type,
int target_number,
kmp_affinity_mask_target_t *mask
);
extern int kmp_get_affinity_target(
TARGET_TYPE target_type,
int target_number,
kmp_affinity_mask_target_t *mask
);
extern int kmp_get_affinity_max_proc_target(
TARGET_TYPE target_type,
int target_number
);
extern int kmp_set_affinity_mask_proc_target(
TARGET_TYPE target_type,
int target_number,
int proc,
kmp_affinity_mask_target_t *mask
);
extern int kmp_unset_affinity_mask_proc_target(
TARGET_TYPE target_type,
int target_number,
int proc,
kmp_affinity_mask_target_t *mask
);
extern int kmp_get_affinity_mask_proc_target(
TARGET_TYPE target_type,
int target_number,
int proc,
kmp_affinity_mask_target_t *mask
);
#ifdef __cplusplus
} /* extern "C" */
/* Namespace for the shared_allocator. */
namespace __offload {
/* This follows the specification for std::allocator. */
/* Forward declaration of the class template. */
template <typename T>
class shared_allocator;
/* Specialization for shared_allocator<void>. */
template <>
class shared_allocator<void> {
public:
typedef void *pointer;
typedef const void *const_pointer;
typedef void value_type;
template <class U> struct rebind { typedef shared_allocator<U> other; };
};
/* Definition of shared_allocator<T>. */
template <class T>
class shared_allocator {
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T *pointer;
typedef const T *const_pointer;
typedef T &reference;
typedef const T &const_reference;
typedef T value_type;
template <class U> struct rebind { typedef shared_allocator<U> other; };
shared_allocator() throw() { }
shared_allocator(const shared_allocator&) throw() { }
template <class U> shared_allocator(const shared_allocator<U>&) throw() { }
~shared_allocator() throw() { }
pointer address(reference x) const { return &x; }
const_pointer address(const_reference x) const { return &x; }
pointer allocate(
size_type, shared_allocator<void>::const_pointer hint = 0);
void deallocate(pointer p, size_type n);
size_type max_size() const throw() {
return size_type(-1)/sizeof(T);
} /* max_size */
void construct(pointer p, const T& arg) {
::new (p) T(arg);
} /* construct */
void destroy(pointer p) {
p->~T();
} /* destroy */
};
/* Definition for allocate. */
template <class T>
typename shared_allocator<T>::pointer
shared_allocator<T>::allocate(shared_allocator<T>::size_type s,
shared_allocator<void>::const_pointer) {
/* Allocate from shared memory. */
void *ptr = _Offload_shared_malloc(s*sizeof(T));
if (ptr == 0) std::__throw_bad_alloc();
return static_cast<pointer>(ptr);
} /* allocate */
template <class T>
void shared_allocator<T>::deallocate(pointer p,
shared_allocator<T>::size_type) {
/* Free the shared memory. */
_Offload_shared_free(p);
} /* deallocate */
template <typename _T1, typename _T2>
inline bool operator==(const shared_allocator<_T1> &,
const shared_allocator<_T2> &) throw() {
return true;
} /* operator== */
template <typename _T1, typename _T2>
inline bool operator!=(const shared_allocator<_T1> &,
const shared_allocator<_T2> &) throw() {
return false;
} /* operator!= */
} /* __offload */
#endif /* __cplusplus */
#endif /* OFFLOAD_H_INCLUDED */

View File

@@ -0,0 +1,170 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
#if defined(LINUX) || defined(FREEBSD)
#include <mm_malloc.h>
#endif
#include "offload_common.h"
// The debug routines
#if OFFLOAD_DEBUG > 0
void __dump_bytes(
int trace_level,
const void *data,
int len
)
{
if (console_enabled > trace_level) {
const uint8_t *arr = (const uint8_t*) data;
char buffer[4096];
char *bufferp;
int count = 0;
bufferp = buffer;
while (len--) {
sprintf(bufferp, "%02x", *arr++);
bufferp += 2;
count++;
if ((count&3) == 0) {
sprintf(bufferp, " ");
bufferp++;
}
if ((count&63) == 0) {
OFFLOAD_DEBUG_TRACE(trace_level, "%s\n", buffer);
bufferp = buffer;
count = 0;
}
}
if (count) {
OFFLOAD_DEBUG_TRACE(trace_level, "%s\n", buffer);
}
}
}
#endif // OFFLOAD_DEBUG
// The Marshaller and associated routines
void Marshaller::send_data(
const void *data,
int64_t length
)
{
OFFLOAD_DEBUG_TRACE(2, "send_data(%p, %lld)\n",
data, length);
memcpy(buffer_ptr, data, (size_t)length);
buffer_ptr += length;
tfr_size += length;
}
void Marshaller::receive_data(
void *data,
int64_t length
)
{
OFFLOAD_DEBUG_TRACE(2, "receive_data(%p, %lld)\n",
data, length);
memcpy(data, buffer_ptr, (size_t)length);
buffer_ptr += length;
tfr_size += length;
}
// Send function pointer
void Marshaller::send_func_ptr(
const void* data
)
{
const char* name;
size_t length;
if (data != 0) {
name = __offload_funcs.find_name(data);
if (name == 0) {
#if OFFLOAD_DEBUG > 0
if (console_enabled > 2) {
__offload_funcs.dump();
}
#endif // OFFLOAD_DEBUG > 0
LIBOFFLOAD_ERROR(c_send_func_ptr, data);
exit(1);
}
length = strlen(name) + 1;
}
else {
name = "";
length = 1;
}
memcpy(buffer_ptr, name, length);
buffer_ptr += length;
tfr_size += length;
}
// Receive function pointer
void Marshaller::receive_func_ptr(
const void** data
)
{
const char* name;
size_t length;
name = (const char*) buffer_ptr;
if (name[0] != '\0') {
*data = __offload_funcs.find_addr(name);
if (*data == 0) {
#if OFFLOAD_DEBUG > 0
if (console_enabled > 2) {
__offload_funcs.dump();
}
#endif // OFFLOAD_DEBUG > 0
LIBOFFLOAD_ERROR(c_receive_func_ptr, name);
exit(1);
}
length = strlen(name) + 1;
}
else {
*data = 0;
length = 1;
}
buffer_ptr += length;
tfr_size += length;
}
// End of the Marshaller and associated routines
extern void *OFFLOAD_MALLOC(
size_t size,
size_t align
)
{
void *ptr;
int err;
OFFLOAD_DEBUG_TRACE(2, "%s(%lld, %lld)\n", __func__, size, align);
if (align < sizeof(void*)) {
align = sizeof(void*);
}
ptr = _mm_malloc(size, align);
if (ptr == NULL) {
LIBOFFLOAD_ERROR(c_offload_malloc, size, align);
exit(1);
}
OFFLOAD_DEBUG_TRACE(2, "%s returned %p\n", __func__, ptr);
return ptr;
}

View File

@@ -0,0 +1,444 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
/*! \file
\brief The parts of the runtime library common to host and target
*/
#ifndef OFFLOAD_COMMON_H_INCLUDED
#define OFFLOAD_COMMON_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include "offload.h"
#include "offload_table.h"
#include "offload_trace.h"
#include "offload_timer.h"
#include "offload_util.h"
#include "cean_util.h"
#include "dv_util.h"
#include "liboffload_error_codes.h"
#include <stdarg.h>
// The debug routines
// Host console and file logging
extern int console_enabled;
extern int offload_report_level;
#define OFFLOAD_DO_TRACE (offload_report_level == 3)
extern const char *prefix;
extern int offload_number;
#if !HOST_LIBRARY
extern int mic_index;
#endif
#if HOST_LIBRARY
void Offload_Report_Prolog(OffloadHostTimerData* timer_data);
void Offload_Report_Epilog(OffloadHostTimerData* timer_data);
void offload_report_free_data(OffloadHostTimerData * timer_data);
void Offload_Timer_Print(void);
#ifndef TARGET_WINNT
#define OFFLOAD_DEBUG_INCR_OFLD_NUM() \
__sync_add_and_fetch(&offload_number, 1)
#else
#define OFFLOAD_DEBUG_INCR_OFLD_NUM() \
_InterlockedIncrement(reinterpret_cast<long*>(&offload_number))
#endif
#define OFFLOAD_DEBUG_PRINT_TAG_PREFIX() \
printf("%s: ", prefix);
#define OFFLOAD_DEBUG_PRINT_PREFIX() \
printf("%s: ", prefix);
#else
#define OFFLOAD_DEBUG_PRINT_PREFIX() \
printf("%s%d: ", prefix, mic_index);
#endif // HOST_LIBRARY
#define OFFLOAD_TRACE(trace_level, ...) \
if (console_enabled >= trace_level) { \
OFFLOAD_DEBUG_PRINT_PREFIX(); \
printf(__VA_ARGS__); \
fflush(NULL); \
}
#if OFFLOAD_DEBUG > 0
#define OFFLOAD_DEBUG_TRACE(level, ...) \
OFFLOAD_TRACE(level, __VA_ARGS__)
#define OFFLOAD_REPORT(level, offload_number, stage, ...) \
if (OFFLOAD_DO_TRACE) { \
offload_stage_print(stage, offload_number, __VA_ARGS__); \
fflush(NULL); \
}
#define OFFLOAD_DEBUG_TRACE_1(level, offload_number, stage, ...) \
if (OFFLOAD_DO_TRACE) { \
offload_stage_print(stage, offload_number, __VA_ARGS__); \
fflush(NULL); \
} \
if (!OFFLOAD_DO_TRACE) { \
OFFLOAD_TRACE(level, __VA_ARGS__) \
}
#define OFFLOAD_DEBUG_DUMP_BYTES(level, a, b) \
__dump_bytes(level, a, b)
extern void __dump_bytes(
int level,
const void *data,
int len
);
#else
#define OFFLOAD_DEBUG_LOG(level, ...)
#define OFFLOAD_DEBUG_DUMP_BYTES(level, a, b)
#endif
// Runtime interface
#define OFFLOAD_PREFIX(a) __offload_##a
#define OFFLOAD_MALLOC OFFLOAD_PREFIX(malloc)
#define OFFLOAD_FREE(a) _mm_free(a)
// Forward functions
extern void *OFFLOAD_MALLOC(size_t size, size_t align);
// The Marshaller
//! \enum Indicator for the type of entry on an offload item list.
enum OffloadItemType {
c_data = 1, //!< Plain data
c_data_ptr, //!< Pointer data
c_func_ptr, //!< Function pointer
c_void_ptr, //!< void*
c_string_ptr, //!< C string
c_dv, //!< Dope vector variable
c_dv_data, //!< Dope-vector data
c_dv_data_slice, //!< Dope-vector data's slice
c_dv_ptr, //!< Dope-vector variable pointer
c_dv_ptr_data, //!< Dope-vector pointer data
c_dv_ptr_data_slice,//!< Dope-vector pointer data's slice
c_cean_var, //!< CEAN variable
c_cean_var_ptr, //!< Pointer to CEAN variable
c_data_ptr_array, //!< Pointer to data pointer array
c_func_ptr_array, //!< Pointer to function pointer array
c_void_ptr_array, //!< Pointer to void* pointer array
c_string_ptr_array //!< Pointer to char* pointer array
};
#define VAR_TYPE_IS_PTR(t) ((t) == c_string_ptr || \
(t) == c_data_ptr || \
(t) == c_cean_var_ptr || \
(t) == c_dv_ptr)
#define VAR_TYPE_IS_SCALAR(t) ((t) == c_data || \
(t) == c_void_ptr || \
(t) == c_cean_var || \
(t) == c_dv)
#define VAR_TYPE_IS_DV_DATA(t) ((t) == c_dv_data || \
(t) == c_dv_ptr_data)
#define VAR_TYPE_IS_DV_DATA_SLICE(t) ((t) == c_dv_data_slice || \
(t) == c_dv_ptr_data_slice)
//! \enum Specify direction to copy offloaded variable.
enum OffloadParameterType {
c_parameter_unknown = -1, //!< Unknown clause
c_parameter_nocopy, //!< Variable listed in "nocopy" clause
c_parameter_in, //!< Variable listed in "in" clause
c_parameter_out, //!< Variable listed in "out" clause
c_parameter_inout //!< Variable listed in "inout" clause
};
//! An Offload Variable descriptor
struct VarDesc {
//! OffloadItemTypes of source and destination
union {
struct {
uint8_t dst : 4; //!< OffloadItemType of destination
uint8_t src : 4; //!< OffloadItemType of source
};
uint8_t bits;
} type;
//! OffloadParameterType that describes direction of data transfer
union {
struct {
uint8_t in : 1; //!< Set if IN or INOUT
uint8_t out : 1; //!< Set if OUT or INOUT
};
uint8_t bits;
} direction;
uint8_t alloc_if; //!< alloc_if modifier value
uint8_t free_if; //!< free_if modifier value
uint32_t align; //!< MIC alignment requested for pointer data
//! Not used by compiler; set to 0
/*! Used by runtime as offset to data from start of MIC buffer */
uint32_t mic_offset;
//! Flags describing this variable
union {
struct {
//! source variable has persistent storage
uint32_t is_static : 1;
//! destination variable has persistent storage
uint32_t is_static_dstn : 1;
//! has length for c_dv && c_dv_ptr
uint32_t has_length : 1;
//! persisted local scalar is in stack buffer
uint32_t is_stack_buf : 1;
//! buffer address is sent in data
uint32_t sink_addr : 1;
//! alloc displacement is sent in data
uint32_t alloc_disp : 1;
//! source data is noncontiguous
uint32_t is_noncont_src : 1;
//! destination data is noncontiguous
uint32_t is_noncont_dst : 1;
};
uint32_t bits;
} flags;
//! Not used by compiler; set to 0
/*! Used by runtime as offset to base from data stored in a buffer */
int64_t offset;
//! Element byte-size of data to be transferred
/*! For dope-vector, the size of the dope-vector */
int64_t size;
union {
//! Set to 0 for array expressions and dope-vectors
/*! Set to 1 for scalars */
/*! Set to value of length modifier for pointers */
int64_t count;
//! Displacement not used by compiler
int64_t disp;
};
//! This field not used by OpenMP 4.0
/*! The alloc section expression in #pragma offload */
union {
void *alloc;
int64_t ptr_arr_offset;
};
//! This field not used by OpenMP 4.0
/*! The into section expression in #pragma offload */
/*! For c_data_ptr_array this is the into ptr array */
void *into;
//! For an ordinary variable, address of the variable
/*! For c_cean_var (C/C++ array expression),
pointer to arr_desc, which is an array descriptor. */
/*! For c_data_ptr_array (array of data pointers),
pointer to ptr_array_descriptor,
which is a descriptor for pointer array transfers. */
void *ptr;
};
//! Auxiliary struct used when -g is enabled that holds variable names
struct VarDesc2 {
const char *sname; //!< Source name
const char *dname; //!< Destination name (when "into" is used)
};
/*! When the OffloadItemType is c_data_ptr_array
the ptr field of the main descriptor points to this struct. */
/*! The type in VarDesc1 merely says c_cean_data_ptr, but the pointer
type can be c_data_ptr, c_func_ptr, c_void_ptr, or c_string_ptr.
Therefore the actual pointer type is in the flags field of VarDesc3. */
/*! If flag_align_is_array/flag_alloc_if_is_array/flag_free_if_is_array
is 0 then alignment/alloc_if/free_if are specified in VarDesc1. */
/*! If flag_align_is_array/flag_alloc_if_is_array/flag_free_if_is_array
is 1 then align_array/alloc_if_array/free_if_array specify
the set of alignment/alloc_if/free_if values. */
/*! For the other fields, if neither the scalar nor the array flag
is set, then that modifier was not specified. If the bits are set
they specify which modifier was set and whether it was a
scalar or an array expression. */
struct VarDesc3
{
void *ptr_array; //!< Pointer to arr_desc of array of pointers
void *align_array; //!< Scalar value or pointer to arr_desc
void *alloc_if_array; //!< Scalar value or pointer to arr_desc
void *free_if_array; //!< Scalar value or pointer to arr_desc
void *extent_start; //!< Scalar value or pointer to arr_desc
void *extent_elements; //!< Scalar value or pointer to arr_desc
void *into_start; //!< Scalar value or pointer to arr_desc
void *into_elements; //!< Scalar value or pointer to arr_desc
void *alloc_start; //!< Scalar value or pointer to arr_desc
void *alloc_elements; //!< Scalar value or pointer to arr_desc
/*! Flags that describe the pointer type and whether each field
is a scalar value or an array expression. */
/*! First 6 bits are pointer array element type:
c_data_ptr, c_func_ptr, c_void_ptr, c_string_ptr */
/*! Then single bits specify: */
/*! align_array is an array */
/*! alloc_if_array is an array */
/*! free_if_array is an array */
/*! extent_start is a scalar expression */
/*! extent_start is an array expression */
/*! extent_elements is a scalar expression */
/*! extent_elements is an array expression */
/*! into_start is a scalar expression */
/*! into_start is an array expression */
/*! into_elements is a scalar expression */
/*! into_elements is an array expression */
/*! alloc_start is a scalar expression */
/*! alloc_start is an array expression */
/*! alloc_elements is a scalar expression */
/*! alloc_elements is an array expression */
uint32_t array_fields;
};
const int flag_align_is_array = 6;
const int flag_alloc_if_is_array = 7;
const int flag_free_if_is_array = 8;
const int flag_extent_start_is_scalar = 9;
const int flag_extent_start_is_array = 10;
const int flag_extent_elements_is_scalar = 11;
const int flag_extent_elements_is_array = 12;
const int flag_into_start_is_scalar = 13;
const int flag_into_start_is_array = 14;
const int flag_into_elements_is_scalar = 15;
const int flag_into_elements_is_array = 16;
const int flag_alloc_start_is_scalar = 17;
const int flag_alloc_start_is_array = 18;
const int flag_alloc_elements_is_scalar = 19;
const int flag_alloc_elements_is_array = 20;
// The Marshaller
class Marshaller
{
private:
// Start address of buffer
char *buffer_start;
// Current pointer within buffer
char *buffer_ptr;
// Physical size of data sent (including flags)
long long buffer_size;
// User data sent/received
long long tfr_size;
public:
// Constructor
Marshaller() :
buffer_start(0), buffer_ptr(0),
buffer_size(0), tfr_size(0)
{
}
// Return count of user data sent/received
long long get_tfr_size() const
{
return tfr_size;
}
// Return pointer to buffer
char *get_buffer_start() const
{
return buffer_start;
}
// Return current size of data in buffer
long long get_buffer_size() const
{
return buffer_size;
}
// Set buffer pointer
void init_buffer(
char *d,
long long s
)
{
buffer_start = buffer_ptr = d;
buffer_size = s;
}
// Send data
void send_data(
const void *data,
int64_t length
);
// Receive data
void receive_data(
void *data,
int64_t length
);
// Send function pointer
void send_func_ptr(
const void* data
);
// Receive function pointer
void receive_func_ptr(
const void** data
);
};
// End of the Marshaller
// The offloaded function descriptor.
// Sent from host to target to specify which function to run.
// Also, sets console and file tracing levels.
struct FunctionDescriptor
{
// Input data size.
long long in_datalen;
// Output data size.
long long out_datalen;
// Whether trace is requested on console.
// A value of 1 produces only function name and data sent/received.
// Values > 1 produce copious trace information.
uint8_t console_enabled;
// Flag controlling timing on the target side.
// Values > 0 enable timing on sink.
uint8_t timer_enabled;
int offload_report_level;
int offload_number;
// number of variable descriptors
int vars_num;
// inout data offset if data is passed as misc/return data
// otherwise it should be zero.
int data_offset;
// The name of the offloaded function
char data[];
};
// typedef OFFLOAD.
// Pointer to OffloadDescriptor.
typedef struct OffloadDescriptor *OFFLOAD;
#endif // OFFLOAD_COMMON_H_INCLUDED

Some files were not shown because too many files have changed in this diff Show More