Set xflag for Python/Shell scripts w/ shebang, removed trailing wspace/tabs and 'tools/mic' (#499)

Set executable flag (Python/Shell scripts w/ shebang), removed trailing whitespaces and tabs. Removed tools/mic (outdated/non-working KNC/offload support).
This commit is contained in:
Hans Pabst 2019-08-02 15:54:51 +02:00 committed by GitHub
parent 004f0d62fa
commit cfeaaad94f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
55 changed files with 84 additions and 6884 deletions

View file

@ -28,7 +28,7 @@ int m_cpuid_static(void)
return CP_MACHINE_X86_SSE4;
#else
return CP_MACHINE_CPU_GENERIC;
#endif
#endif
}
#if defined(__cplusplus)

View file

@ -26,8 +26,8 @@ static const int max_2d_plans = 0;
static const int max_1d_plans = 30;
static const int sum_plans = max_3d_plans + max_2d_plans + max_1d_plans;
static const int max_plans = sum_plans > 1? sum_plans : 1;
static const int sum_plans = max_3d_plans + max_2d_plans + max_1d_plans;
static const int max_plans = sum_plans > 1? sum_plans : 1;
#if (__CUDACC_VER_MAJOR__<8)
// configuration(s)

View file

@ -38,8 +38,8 @@ void pw_fpga_final_(){
}
/******************************************************************************
* \brief check whether FFT3d can be computed on the FPGA or not. This depends
* on the availability of bitstreams whose sizes are for now listed here
* \brief check whether FFT3d can be computed on the FPGA or not. This depends
* on the availability of bitstreams whose sizes are for now listed here
* If the fft sizes are found and the FPGA is not setup before, it is done
* \param data_path - path to the data directory
* \param N - integer pointer to the size of the FFT3d
@ -86,11 +86,11 @@ int pw_fpga_check_bitstream_(char *data_path, int N[3]){
/******************************************************************************
* \brief compute an in-place single precision complex 3D-FFT on the FPGA
* \param direction : direction - 1/forward, otherwise/backward FFT3d
* \param N : integer pointer to size of FFT3d
* \param din : complex input/output single precision data pointer
* \param N : integer pointer to size of FFT3d
* \param din : complex input/output single precision data pointer
*****************************************************************************/
void pw_fpga_fft3d_sp_(int direction, int N[3], cmplx *din) {
// setup device specific constructs
// setup device specific constructs
if(direction == 1){
fftfpga_run_3d(0, N, din);
}
@ -102,11 +102,11 @@ void pw_fpga_fft3d_sp_(int direction, int N[3], cmplx *din) {
/******************************************************************************
* \brief compute an in-place double precision complex 3D-FFT on the FPGA
* \param direction : direction - 1/forward, otherwise/backward FFT3d
* \param N : integer pointer to size of FFT3d
* \param din : complex input/output single precision data pointer
* \param N : integer pointer to size of FFT3d
* \param din : complex input/output single precision data pointer
*****************************************************************************/
void pw_fpga_fft3d_dp_(int direction, int N[3], cmplx *din) {
// setup device specific constructs
// setup device specific constructs
if(direction == 1){
fftfpga_run_3d(0, N, din);
}
@ -118,15 +118,15 @@ void pw_fpga_fft3d_dp_(int direction, int N[3], cmplx *din) {
/******************************************************************************
* \brief Execute a single precision complex FFT3d
* \param inverse : int
* \param N : integer pointer to size of FFT3d
* \param din : complex input/output single precision data pointer
* \param N : integer pointer to size of FFT3d
* \param din : complex input/output single precision data pointer
*****************************************************************************/
void fftfpga_run_3d(int inverse, int N[3], cmplx *c_in) {
cl_int status = 0;
int inverse_int = inverse;
cl_kernel fft_kernel = NULL, fft_kernel_2 = NULL;
cl_kernel fetch_kernel = NULL, transpose_kernel = NULL, transpose_kernel_2 = NULL;
// Device memory buffers
cl_mem d_inData, d_outData;
@ -216,25 +216,25 @@ void fftfpga_run_3d(int inverse, int N[3], cmplx *c_in) {
queue_cleanup();
if (h_outData)
free(h_outData);
free(h_outData);
if (h_inData)
free(h_inData);
free(h_inData);
if (d_inData)
clReleaseMemObject(d_inData);
if (d_outData)
clReleaseMemObject(d_outData);
clReleaseMemObject(d_inData);
if (d_outData)
clReleaseMemObject(d_outData);
if(fetch_kernel)
clReleaseKernel(fetch_kernel);
if(fft_kernel)
clReleaseKernel(fft_kernel);
if(fft_kernel_2)
clReleaseKernel(fft_kernel_2);
if(transpose_kernel)
clReleaseKernel(transpose_kernel);
if(transpose_kernel_2)
clReleaseKernel(transpose_kernel_2);
if(fetch_kernel)
clReleaseKernel(fetch_kernel);
if(fft_kernel)
clReleaseKernel(fft_kernel);
if(fft_kernel_2)
clReleaseKernel(fft_kernel_2);
if(transpose_kernel)
clReleaseKernel(transpose_kernel);
if(transpose_kernel_2)
clReleaseKernel(transpose_kernel_2);
}
@ -267,7 +267,7 @@ void init_program(int N[3], char *data_path){
* \brief Free resources allocated during program initialization
*****************************************************************************/
void cleanup_program(){
if(program)
if(program)
clReleaseProgram(program);
if(context)
clReleaseContext(context);
@ -325,17 +325,17 @@ void queue_setup(){
* \brief Release all command queues
*****************************************************************************/
void queue_cleanup() {
if(queue1)
if(queue1)
clReleaseCommandQueue(queue1);
if(queue2)
if(queue2)
clReleaseCommandQueue(queue2);
if(queue3)
if(queue3)
clReleaseCommandQueue(queue3);
if(queue4)
if(queue4)
clReleaseCommandQueue(queue4);
if(queue5)
if(queue5)
clReleaseCommandQueue(queue5);
if(queue6)
if(queue6)
clReleaseCommandQueue(queue6);
}

View file

@ -66,7 +66,7 @@ cl_platform_id findPlatform(char *platform_name){
size_t sz;
for(i=0; i<num_platforms; i++){
// Get the size of the platform name referred to by the id
status = clGetPlatformInfo(pids[i], CL_PLATFORM_NAME, 0, NULL, &sz);
status = clGetPlatformInfo(pids[i], CL_PLATFORM_NAME, 0, NULL, &sz);
if (status != CL_SUCCESS){
printf("Query for platform info failed\n");
free(pids);
@ -77,7 +77,7 @@ cl_platform_id findPlatform(char *platform_name){
char plat_name[sz];
// Store the name of string size
status = clGetPlatformInfo(pids[i], CL_PLATFORM_NAME, sz, pl_name, NULL);
status = clGetPlatformInfo(pids[i], CL_PLATFORM_NAME, sz, pl_name, NULL);
if (status != CL_SUCCESS){
printf("Query for platform info failed\n");
free(pids);
@ -97,7 +97,7 @@ cl_platform_id findPlatform(char *platform_name){
/******************************************************************************
* \brief returns the list of all devices for the specfic platform
* \param platform id to search for devices
* \param platform id to search for devices
* \param specific type of device to search for
* \param total number of devices found for the given platform
* \retval array of device ids
@ -155,7 +155,7 @@ cl_program getProgramWithBinary(cl_context context, const cl_device_id *devices,
#endif
char *foldername;
const char *filename = "fft3d.aocx";
if( !getFolderPath(&foldername, N) ){
printf("Path not found for the size (%d,%d,%d)", N[0], N[1], N[2]);
return NULL;
@ -207,7 +207,7 @@ int getFolderPath(char **folderPath, int N[3]){
char folder[] = "syn32/";
*folderPath = malloc(strlen(folder)+1);
strncpy(*folderPath, folder, strlen(folder));
}
}
else if (N[0] == 64 && N[1] == 64 && N[2] == 64){
char folder[] = "syn64/";
*folderPath = malloc(strlen(folder)+1);
@ -247,7 +247,7 @@ static size_t loadBinary(char *binary_path, char **buf){
}
/******************************************************************************
* \brief Allocate host side buffers to be 64-byte aligned to make use of DMA
* \brief Allocate host side buffers to be 64-byte aligned to make use of DMA
* transfer between host and global memory
* \param size in bytes : allocate size bytes multiples of 64
* \retval pointer to allocated memory on successful allocation otherwise NULL
@ -353,7 +353,7 @@ void _checkError(const char *file, int line, const char *func, cl_int err, const
printError(err);
printf("\nError Location: %s:%d:%s\n", file, line, func);
// custom message
// custom message
va_list vl;
va_start(vl, msg);
vprintf(msg, vl);
@ -369,7 +369,7 @@ void _checkError(const char *file, int line, const char *func, cl_int err, const
/******************************************************************************
* \brief converts a given null-terminated string to lowercase and stores in q
* \param p : null-terminated string
* \param q : string with (strlen(p)+1) length
* \param q : string with (strlen(p)+1) length
*****************************************************************************/
static void tolowercase(char *p, char *q){
int i;

View file

@ -9,7 +9,7 @@
!> \author Teodoro Laino [tlaino] - University of Zurich
!> \date 04.2008 [tlaino]
! *****************************************************************************
INTERFACE
INTERFACE
SUBROUTINE check_rotmat_der( sepi, sepj, rjiv, ij_matrix, do_invert)
USE kinds, ONLY: dp
USE semi_empirical_types, ONLY: rotmat_type,&
@ -20,7 +20,7 @@ INTERFACE
TYPE(rotmat_type), POINTER :: ij_matrix
LOGICAL, INTENT(IN) :: do_invert
END SUBROUTINE check_rotmat_der
END INTERFACE
END INTERFACE
! *****************************************************************************
!> \brief Check Numerical Vs Analytical NUCINT ssss
@ -45,7 +45,7 @@ INTERFACE
TYPE(se_int_control_type), INTENT(IN) :: se_int_control
TYPE(se_taper_type), POINTER :: se_taper
END SUBROUTINE check_dssss_nucint_ana
END INTERFACE
END INTERFACE
! *****************************************************************************
!> \brief Check Numerical Vs Analytical NUCINT core
@ -55,7 +55,7 @@ END INTERFACE
!> 04.2008 created [tlaino]
!> \author Teodoro Laino - Zurich University
! *****************************************************************************
INTERFACE
INTERFACE
SUBROUTINE check_dcore_nucint_ana (sepi,sepj,r,dcore,itype,se_int_control,&
se_taper)
USE kinds, ONLY: dp
@ -70,7 +70,7 @@ INTERFACE
TYPE(se_int_control_type), INTENT(IN) :: se_int_control
TYPE(se_taper_type), POINTER :: se_taper
END SUBROUTINE check_dcore_nucint_ana
END INTERFACE
END INTERFACE
! *****************************************************************************
!> \brief Check Numerical Vs Analytical ROTNUC
@ -80,7 +80,7 @@ END INTERFACE
!> 04.2008 created [tlaino]
!> \author Teodoro Laino - Zurich University
! *****************************************************************************
INTERFACE
INTERFACE
SUBROUTINE check_drotnuc_ana(sepi, sepj, rijv, itype, se_int_control, se_taper,&
e1b, e2a, de1b, de2a)
USE kinds, ONLY: dp
@ -98,7 +98,7 @@ INTERFACE
REAL(dp), DIMENSION(45, 3), &
INTENT(IN), OPTIONAL :: de1b, de2a
END SUBROUTINE check_drotnuc_ana
END INTERFACE
END INTERFACE
! *****************************************************************************
!> \brief Check Numerical Vs Analytical CORECORE
@ -108,7 +108,7 @@ END INTERFACE
!> 04.2008 created [tlaino]
!> \author Teodoro Laino - Zurich University
! *****************************************************************************
INTERFACE
INTERFACE
SUBROUTINE check_dcorecore_ana(sepi, sepj, rijv, itype,se_int_control,&
se_taper, enuc, denuc)
USE kinds, ONLY: dp
@ -126,7 +126,7 @@ INTERFACE
TYPE(se_taper_type), POINTER :: se_taper
END SUBROUTINE check_dcorecore_ana
END INTERFACE
END INTERFACE
! *****************************************************************************
!> \brief Check Numerical Vs Analytical rot_2el_2c_first
@ -136,7 +136,7 @@ END INTERFACE
!> 04.2008 created [tlaino]
!> \author Teodoro Laino - Zurich University
! *****************************************************************************
INTERFACE
INTERFACE
SUBROUTINE rot_2el_2c_first_debug(sepi, sepj, rijv, se_int_control, se_taper,&
invert, ii, kk, v_d)
USE kinds, ONLY: dp
@ -153,7 +153,7 @@ INTERFACE
REAL(KIND=dp), DIMENSION(45, 45, 3), &
INTENT(IN) :: v_d
END SUBROUTINE rot_2el_2c_first_debug
END INTERFACE
END INTERFACE
! *****************************************************************************
!> \brief Check Numerical Vs Analytical check_dterep_ana
@ -163,7 +163,7 @@ END INTERFACE
!> 04.2008 created [tlaino]
!> \author Teodoro Laino - Zurich University
! *****************************************************************************
INTERFACE
INTERFACE
SUBROUTINE check_dterep_ana (sepi,sepj,r,ri,dri,se_int_control,se_taper,lgrad)
USE kinds, ONLY: dp
USE semi_empirical_types, ONLY: semi_empirical_type,&
@ -177,7 +177,7 @@ INTERFACE
LOGICAL, INTENT(IN) :: lgrad
TYPE(se_taper_type), POINTER :: se_taper
END SUBROUTINE check_dterep_ana
END INTERFACE
END INTERFACE
! *****************************************************************************
!> \brief Check Numerical Vs Analytical check_rotint_ana
@ -187,7 +187,7 @@ END INTERFACE
!> 04.2008 created [tlaino]
!> \author Teodoro Laino - Zurich University
! *****************************************************************************
INTERFACE
INTERFACE
SUBROUTINE check_rotint_ana(sepi,sepj,rijv,w,dw,se_int_control,se_taper)
USE kinds, ONLY: dp
USE semi_empirical_types, ONLY: semi_empirical_type,&
@ -203,4 +203,4 @@ INTERFACE
TYPE(se_int_control_type), INTENT(IN) :: se_int_control
TYPE(se_taper_type), POINTER :: se_taper
END SUBROUTINE check_rotint_ana
END INTERFACE
END INTERFACE

View file

@ -65,41 +65,41 @@ Args:
{
int sockfd, ai_err;
if (*inet>0)
{ // creates an internet socket
// fetches information on the host
struct addrinfo hints, *res;
// fetches information on the host
struct addrinfo hints, *res;
char service[256];
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = AF_INET;
hints.ai_flags = AI_PASSIVE;
sprintf(service,"%d",*port); // convert the port number to a string
ai_err = getaddrinfo(host, service, &hints, &res);
ai_err = getaddrinfo(host, service, &hints, &res);
if (ai_err!=0) { perror("Error fetching host data. Wrong host name?"); exit(-1); }
// creates socket
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sockfd < 0) { perror("Error opening socket"); exit(-1); }
// makes connection
if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0) { perror("Error opening INET socket: wrong port or server unreachable"); exit(-1); }
freeaddrinfo(res);
}
else
{ // creates a unix socket
struct sockaddr_un serv_addr;
struct sockaddr_un serv_addr;
// fills up details of the socket addres
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sun_family = AF_UNIX;
strcpy(serv_addr.sun_path, "/tmp/ipi_");
strcpy(serv_addr.sun_path+9, host);
// creates the socket
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
@ -161,7 +161,7 @@ void uwait(double *dsec)
{
int rn;
struct timespec wt, rem;
wt.tv_sec = floor(*dsec); wt.tv_nsec=(*dsec-wt.tv_sec)*1000000000;
wt.tv_sec = floor(*dsec); wt.tv_nsec=(*dsec-wt.tv_sec)*1000000000;
rn = nanosleep(&wt, &rem);
}

View file

@ -62,7 +62,7 @@ collocate_fast.o:
integrate_fast.o:
\$(FC_tune) -I../ -c integrate_fast.F -o integrate_fast.o
qs_collocate_density.o:
\$(FC_tune) -I../ -c qs_collocate_density.F -o qs_collocate_density.o
\$(FC_tune) -I../ -c qs_collocate_density.F -o qs_collocate_density.o
qs_integrate_potential.o:
\$(FC_tune) -I../ -c qs_integrate_potential.F -o qs_integrate_potential.o
main.o: qs_collocate_density.o qs_integrate_potential.o integrate_fast.o collocate_fast.o
@ -71,7 +71,7 @@ test.x: main.o qs_integrate_potential.o qs_collocate_density.o integrate_fast.o
\$(FC_tune) qs_collocate_density.o qs_integrate_potential.o collocate_fast.o integrate_fast.o main.o ../libtest.a -o test.x
" > makefile_case
#7 ! generate up to l = l_max_a + l_max_b
#7 ! generate up to l = l_max_a + l_max_b
#1 ! use the best of three timings
Ncomb=$(( 2**$Nopt ))
TARGETS_EXE=""

20
tools/autotune_grid/get_results.sh Normal file → Executable file
View file

@ -2,7 +2,7 @@
#
# get_results
# ==============================================
# Extract the best combinations from all the
# Extract the best combinations from all the
# directories.
#
# @author: Ruyman Reyes (rreyesc@epcc.ed.ac.uk)
@ -34,9 +34,9 @@ echo "l Time Opt" > best_timings
continue
fi
# echo "($error) Error was $tmp , accepted $iopt"
# Extract the time of the combination
# Extract the time of the combination
tmp=$(cat out_${l}_${iopt}/out_test_${l}_${iopt}_T_${icollo} | tr -s ' ' | grep "best time" | cut -f 5 -d ' ')
test "$tmp" || continue
dif=$(python -c "print $bsf>$tmp")
@ -71,12 +71,12 @@ done # for icollo
echo " Generating optimal combination "
(
echo $lmax
for l in `seq 0 $lmax`; do
echo ${bsf_iopt_global_0[$l]}
done
echo $lmax
for l in `seq 0 $lmax`; do
echo ${bsf_iopt_global_1[$l]}
done
for l in `seq 0 $lmax`; do
echo ${bsf_iopt_global_0[$l]}
done
echo $lmax
for l in `seq 0 $lmax`; do
echo ${bsf_iopt_global_1[$l]}
done
) > generate_best

View file

@ -1 +0,0 @@
!/include/

View file

@ -1,28 +0,0 @@
Copyright (c) 2014-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1,217 +0,0 @@
# LIBXSTREAM
Library to work with streams, events, and code regions that are able to run asynchronous while preserving the usual stream conditions. The library is targeting Intel Architecture (x86) and helps to offload work to an Intel Xeon Phi coprocessor (an instance of the Intel Many Integrated Core "MIC" Architecture). For example, using two streams may be an alternative to the usual double-buffering approach which can be used to hide buffer transfer time behind compute. [[pdf](https://github.com/hfp/libxstream/raw/master/documentation/libxstream.pdf)] [[src](https://github.com/hfp/libxstream/archive/v0.8.0.zip)]
## Interface
The library's application programming interface (API) completely seals the implementation and only forward-declares types which are beyond the language's built-in types. The entire API consists of below subcategories each illustrated by a small code snippet. The [Function Interface](#function-interface) for instance enables an own function to be enqueued for execution within a stream (via function pointer). A future release of the library will provide a native FORTRAN interface. [[c](https://github.com/hfp/libxstream/blob/master/include/libxstream.h)]
### Data Types
Data types are forward-declared types used in the interface. Moreover, there is a mapping from the language's built-in types to the types supported in the [Function Interface](#function-interface).
```C
/** Boolean state. */
typedef int libxstream_bool;
/** Stream type. */
typedef struct libxstream_stream libxstream_stream;
/** Event type. */
typedef struct libxstream_event libxstream_event;
/** Enumeration of elemental "scalar" types. */
typedef enum libxstream_type { /** see libxstream.h */
/** special types: BOOL, BYTE, CHAR, VOID */
/** signed integer types: I8, I16, I32, I64 */
/** unsigned integer types: U8, U16, U32, U64 */
/** floating point types: F32, F64, C32, C64 */
} libxstream_type;
/** Function call behavior (flags valid for binary combination). */
typedef enum libxstream_call_flags {
LIBXSTREAM_CALL_WAIT = 1 /* synchronous function call */,
LIBXSTREAM_CALL_NATIVE = 2 /* native host/MIC function */,
/** collection of any valid flags from above */
LIBXSTREAM_CALL_DEFAULT = 0
} libxstream_call_flags;
/** Function argument type. */
typedef struct libxstream_argument libxstream_argument;
/** Function type of an offloadable function. */
typedef void (*libxstream_function)(LIBXSTREAM_VARIADIC);
```
### Device Interface
The device interface provides the notion of an "active device" (beside of allowing to query the number of available devices). Multiple active devices can be specified on a per host-thread basis. None of the other functions of the API implies an active device. It is up to the user to make use of this notion.
```C
size_t ndevices = 0;
libxstream_get_ndevices(&ndevices);
```
### Memory Interface
The memory interface is mainly for handling device-side buffers (allocation, copy). It is usually beneficial to allocate host memory using these functions as well. However, any memory allocation on the host is interoperable. It is also supported copying parts to/from a buffer.
```C
const int hst = -1, dev = 0;
libxstream_mem_allocate(hst, &ihst, sizeof(double) * nitems, 0/*auto-alignment*/);
libxstream_mem_allocate(hst, &ohst, sizeof(double) * nitems, 0/*auto-alignment*/);
/* TODO: initialize with some input data */
libxstream_mem_allocate(dev, &idev, sizeof(double) * nbatch, 0/*auto-alignment*/);
libxstream_mem_allocate(dev, &odev, sizeof(double) * nbatch, 0/*auto-alignment*/);
for (int i = 0; i < nitems; i += nbatch) {
const int ibatch = sizeof(double) * min(nbatch, nitems - i), j = i / nbatch;
libxstream_memcpy_h2d(ihst + i, idev, ibatch, stream[j%2]);
/* TODO: invoke user function (see Function Interface) */
libxstream_memcpy_d2h(odev, ohst + i, ibatch, stream[j%2]);
}
libxstream_mem_deallocate(hst, ihst);
libxstream_mem_deallocate(hst, ohst);
libxstream_mem_deallocate(dev, idev);
libxstream_mem_deallocate(dev, odev);
```
### Stream Interface
The stream interface is used to expose the available parallelism. A stream preserves the predecessor/successor relationship while participating in a pipeline (parallel pattern) in case of multiple streams. Synchronization points can be introduced using the stream interface as well as the [Event Interface](#event-interface).
```C
libxstream_stream* stream[2];
libxstream_stream_create(stream + 0, d, 1/*demux*/, 0/*priority*/, "s1");
libxstream_stream_create(stream + 1, d, 1/*demux*/, 0/*priority*/, "s2");
/* TODO: do something with the streams */
libxstream_stream_sync(NULL); /*wait for all streams*/
libxstream_stream_destroy(stream[0]);
libxstream_stream_destroy(stream[1]);
```
### Event Interface
The event interface provides a more sophisticated mechanism allowing to wait for a specific work item to complete without the need to also wait for the completion of work queued after the item in question.
```C
libxstream_event* event[2/*N*/];
libxstream_event_create(event + 0);
libxstream_event_create(event + 1);
for (int i = 0; i < nitems; i += nbatch) {
const size_t j = i / nbatch, n = j % N;
/* TODO: copy-in, user function, copy-out */
libxstream_event_record(event + n, stream + n);
/* synchronize every Nth iteration */
if (n == (N - 1)) {
for (size_t k = 0; k < N; ++k) {
libxstream_event_synchronize(event[k]);
}
}
}
libxstream_event_destroy(event[0]);
libxstream_event_destroy(event[1]);
```
### Function Interface
The function interface is used to call a user function and to describe its list of arguments (signature). The function's signature consists of inputs, outputs, or in-out arguments. An own function can be enqueued for execution within a stream by taking the address of the function.
```C
size_t nargs = 5, arity = 0;
libxstream_argument* args = 0;
libxstream_fn_create_signature(&args, nargs/*maximum number of arguments*/);
libxstream_fn_nargs (args, &nargs); /*nargs==5 (maximum number of arguments)*/
libxstream_get_arity(args, &arity); /*arity==0 (no arguments constructed yet)*/
libxstream_fn_call((libxstream_function)f, args, stream, LIBXSTREAM_CALL_DEFAULT);
libxstream_fn_destroy_signature(args); /*(can be used for many function calls)*/
```
In order to avoid repeatedly allocating (and deallocating) a signature, a thread-local signature with the maximum number of arguments supported can be constructed i.e., the thread-local signature is cleared to allow starting over with an arity of zero.
```C
libxstream_fn_signature(&args); /*do not call libxstream_fn_destroy_signature!*/
libxstream_fn_nargs(args, &nargs); /*nargs==LIBXSTREAM_MAX_NARGS*/
```
**void fc(const double* scale, const float* in, float* out, const size_t* n, size_t* nzeros)**
For the C language, a first observation is that all arguments of the function's signature are passed "by pointer"; even a value that needs to be returned (which also allows multiple results to be delivered). Please note that non-elemental ("array") arguments are handled "by pointer" rather than by pointer-to-pointer. The mechanism to pass an argument is called "by-pointer" (or by-address) to distinct from the C++ reference type mechanism. Although all arguments are received by pointer, any elemental ("scalar") input is present by value (which is important for the argument's life-time). In contrast, an elemental output is only present by-address, and therefore care must be taken on the call-side to ensure the destination is still valid when the function is executed. The latter is because the execution is asynchronous by default.
**void fpp(const double& scale, const float* in, float* out, const size_t& n, size_t& nzeros)**
For the C++ language, the reference mechanism can be used to conveniently receive an elemental argument "by-value" including elemental output arguments as "non-const reference" ("return value").
```C++
const libxstream_type sizetype = libxstream_map_to<size_t>::type();
libxstream_fn_input (args, 0, &scale, libxstream_map_to_type(scale), 0, NULL);
libxstream_fn_input (args, 1, in, LIBXSTREAM_TYPE_F32, 1, &n);
libxstream_fn_output(args, 2, out, LIBXSTREAM_TYPE_F32, 1, &n);
libxstream_fn_input (args, 3, &n, sizetype, 0, NULL);
libxstream_fn_output(args, 4, &nzeros, sizetype, 0, NULL);
```
Beside of showing some C++ syntax in the above code snippet, the resulting signature is perfectly valid for both the "fc" and the "fpp" function.
**Weak type information**
To construct a signature with only weak type information, one may (1) not distinct between inout and output arguments; even non-elemental inputs can be treated as an inout argument, and (2) use LIBXSTREAM_TYPE_VOID as an elemental type or any other type with a type-size of one (BYTE, I8, U8, CHAR). The latter implies that all extents are counted in Byte rather than in number of elements. Moreover, scalar arguments now need to supply a "shape" indicating the actual size of the element in Byte.
```C
const size_t typesize = sizeof(float);
/* argument type in function signature: const float* or const float& */
libxstream_fn_input(args, 0, &f1, LIBXSTREAM_TYPE_VOID, 0, &typesize);
/* argument type in function signature: unsigned char* */
libxstream_fn_inout(args, 1, data, LIBXSTREAM_TYPE_BYTE, 1, &numbytes);
```
### Query Interface
This "device-side API" allows to query information about function arguments when inside of a user function (which is called by the library). This can be used to introspect the function's arguments in terms of type, dimensionality, shape, and other properties. In order to query a property, the position of the argument within the signature needs to be known. However, the position within the signature can be also queried (when inside of a library-initiated call context) by using the actual function argument (given by address). To refer a function's signature when inside of a function, a NULL-pointer is passed to designate the function signature of the current call context.
**Revised function "fc" querying argument properties**
As one can see, the signature of a function can often be trimmed to omit arguments which certainly describe the shape of an argument (below function signature omits the "n" argument shown in one of the previous examples).
```C
LIBXSTREAM_TARGET(mic) void f(const double* scale, const float* in, float* out, size_t* nzeros)
{
size_t in_position = 0;
libxstream_get_argument(in, &in_position); /*in_position == 1*/
size_t arity = 0;
libxstream_get_arity(NULL/*this call context*/, &arity); /*arity == 4*/
size_t n = 0;
libxstream_get_shape(NULL/*this call context*/, in_position, &n);
libxstream_type type = LIBXSTREAM_TYPE_VOID;
libxstream_get_type(NULL/*this call context*/, 2/*out*/, &type);
const char* name = 0;
libxstream_get_typename(type, &name);
printf("type=%s", name); /*f32*/
}
```
## Performance
The [multi-dgemm](https://github.com/hfp/libxstream/tree/master/samples/multi-dgemm) sample code is the implementation of a benchmark (beside of illustrating the use of the library). The shown performance is not meant to be "the best case". Instead, the performance is reproduced by a program constructing a series of matrix-matrix multiplications of varying problem sizes with no attempt to avoid the implied performance penalties (see underneath the graph for more details). A reasonable host system and benchmark implementation is likely able to outperform below results (no transfers, etc.).
![This performance graph has been created for a single Intel Xeon Phi 7120 Coprocessor card by running "OFFLOAD_DEVICES=0 ./[benchmark.sh](https://github.com/hfp/libxstream/blob/master/samples/multi-dgemm/benchmark.sh) 250 1 2" on the host system. The script varies the number of matrix-matrix multiplications queued at once. The program is rather a stress-test than a benchmark since there is no attempt to avoid the performance penalties as mentioned below. The plot shows ~145 GFLOPS/s even with smaller batch sizes.](samples/multi-dgemm/plot.png)
> This performance graph has been created for a single Intel Xeon Phi 7120 Coprocessor card by running "OFFLOAD_DEVICES=0 ./[benchmark.sh](https://github.com/hfp/libxstream/blob/master/samples/multi-dgemm/benchmark.sh) 250 1 2" on the host system. The script varies the number of matrix-matrix multiplications queued at once. The program is rather a stress-test than a benchmark since there is no attempt to avoid the performance penalties as mentioned below. The plot shows ~145 GFLOPS/s even with smaller batch sizes.
Even the series of matrices with the largest problem size of the mix is not close to being able to reach the peak performance, and there is an insufficient amount of FLOPS available to hide the cost of transferring the data. The data needed for the computation moreover includes a set of indices describing the offsets of each of the matrix operands in the associated buffers. The latter implies unaligned memory accesses due to packing the matrix data without a favorable leading dimension. Transfers are performed as needed on a per-computation basis rather than aggregating a single copy-in and copy-out prior and past of the benchmark cycle. Moreover, there is no attempt to balance the mixture of different problem sizes when queuing the work into the streams.
## Tuning
### Hybrid Parallelism
Additional scalability can be unlocked when running an application which is parallelized using the Message Passing Interface (MPI). In this case, the device(s) can be partitioned according to the number of ranks per host processor. To read more about this, please visit the [MPIRUN WRAPPER](https://github.com/hfp/mpirun#mpirun-wrapper) project. To estimate the impact of this technique, one can scale the number of threads on the device until the performance saturates and then partition accordingly.
## Implementation
### Background
The library's implementation allows enqueuing work from multiple host threads in a thread-safe manner and without oversubscribing the device. The actual implementation vehicle can be configured using a [configuration header](https://github.com/hfp/libxstream/blob/master/include/libxstream_config.h). Currently Intel's Language Extensions for Offload (LEO) are used to perform asynchronous execution and data transfers using signal/wait clauses. Other mechanisms can be implemented e.g., hStreams or COI (both are part of the Intel Manycore Platform Software Stack), or offload directives as specified by OpenMP.
The current implementation is falling back to host execution in cases where no coprocessor is present, or when the executable was not built using the Intel Compiler. However, there is no attempt (yet) to exploit the parallelism available on the host system.
### Limitations
There is a known performance limitations addressed by the [Roadmap](#roadmap). Namely the asynchronous offload is currently disabled (see LIBXSTREAM_ASYNC in the [configuration header](https://github.com/hfp/libxstream/blob/master/include/libxstream_config.h)) due to an improper synchronization infrastructure. This issue will be addressed along with scheduling work items. The latter is also a prerequisite for an efficient hybrid execution. Hybrid execution and Transparent High Bandwidth Memory (HBM) support will both rely on an effective association between host and "device" buffers in order to omit unnecessary memory copies.
### Roadmap
Although the library is under development, the interface is stable. There is a high confidence that all features planned are mainly work "under the hood" i.e., code written now can scale forward. The following issues are being addressed in upcoming revisions:
* Transparent High Bandwidth Memory (HBM) support
* Work scheduling and legacy cleanup ("demux")
* Hybrid execution (host and coprocessors)
* Native FORTRAN interface
## Applications and References
**\[1] http://cp2k.org/**: Open Source Molecular Dynamics application. An experimental [branch](https://github.com/cp2k/cp2k/tree/intel) at GitHub uses the library to offload work to an Intel Xeon Phi coprocessor.
**\[2] https://github.com/01org/pyMIC**: Module to offload computation in a Python program to the Intel Xeon Phi coprocessor. The next release uses the library to deliver a stream programming model.
**\[3] http://software.intel.com/xeonphicatalog**: Intel Xeon Phi Applications and Solutions Catalog.
**\[4] [http://goo.gl/qsnOOf](https://software.intel.com/en-us/articles/intel-and-third-party-tools-and-libraries-available-with-support-for-intelr-xeon-phitm)**: Intel 3rd Party Tools and Libraries.

View file

@ -1,38 +0,0 @@
#!/bin/bash
# output basename
BASENAME=$(basename ${PWD})
# temporary file
TEMPLATE=$(mktemp --tmpdir=. --suffix=.tex)
# dump pandoc template for latex
pandoc -D latex > ${TEMPLATE}
# adjust the template
sed -i \
-e 's/\(\\documentclass\[.\+\]{.\+}\)/\1\n\\pagenumbering{gobble}/' \
-e 's/\\usepackage{listings}/\\usepackage{listings}\\lstset{basicstyle=\\footnotesize\\ttfamily}/' \
${TEMPLATE}
# cleanup markup and pipe into pandoc using the template
sed \
-e 's/\[\[.\+\](.\+)\]//' \
-e '/!\[.\+\](.\+)/{n;d}' \
README.md | tee >( \
pandoc \
--latex-engine=xelatex \
--template=${TEMPLATE} --listings \
-f markdown_github+implicit_figures \
-V documentclass=scrartcl \
-V classoption=DIV=45 \
-V linkcolor=black \
-V citecolor=black \
-V urlcolor=black \
-o documentation/${BASENAME}.pdf) | \
pandoc \
-f markdown_github+implicit_figures \
-o documentation/${BASENAME}.docx
# remove temporary file
rm ${TEMPLATE}

View file

@ -1,4 +0,0 @@
{
"description": "LIBXSMM API",
"requires": []
}

View file

@ -1,238 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#ifndef LIBXSTREAM_H
#define LIBXSTREAM_H
#include "libxstream_macros.h"
#include "libxstream_begin.h"
#include <stdint.h>
#include <stddef.h>
#if defined(__cplusplus)
# include <complex>
#endif
#include "libxstream_end.h"
/** Boolean state; must match LIBXSTREAM_TYPE_BOOL. */
typedef int libxstream_bool;
/** Stream type. */
LIBXSTREAM_EXPORT_C typedef struct libxstream_stream libxstream_stream;
/** Event type. */
LIBXSTREAM_EXPORT_C typedef struct libxstream_event libxstream_event;
/** Enumeration of elemental "scalar" types. */
LIBXSTREAM_EXPORT_C typedef enum libxstream_type {
/** special types: BOOL, BYTE, CHAR, VOID */
LIBXSTREAM_TYPE_CHAR,
/** signed integer types: I8, I16, I32, I64 */
LIBXSTREAM_TYPE_I8,
LIBXSTREAM_TYPE_I16,
LIBXSTREAM_TYPE_I32, LIBXSTREAM_TYPE_BOOL = LIBXSTREAM_TYPE_I32,
LIBXSTREAM_TYPE_I64,
/** unsigned integer types: U8, U16, U32, U64 */
LIBXSTREAM_TYPE_U8, LIBXSTREAM_TYPE_BYTE = LIBXSTREAM_TYPE_U8,
LIBXSTREAM_TYPE_U16,
LIBXSTREAM_TYPE_U32,
LIBXSTREAM_TYPE_U64,
/** floating point types: F32, F64, C32, C64 */
LIBXSTREAM_TYPE_F32,
LIBXSTREAM_TYPE_F64,
LIBXSTREAM_TYPE_C32,
LIBXSTREAM_TYPE_C64,
/** terminates type list */
LIBXSTREAM_TYPE_VOID,
LIBXSTREAM_TYPE_INVALID
} libxstream_type;
/** Function call behavior (flags valid for binary combination). */
LIBXSTREAM_EXPORT_C typedef enum libxstream_call_flags {
LIBXSTREAM_CALL_WAIT = 1 /* synchronous function call */,
LIBXSTREAM_CALL_NATIVE = 2 /* native host/MIC function */,
/** terminates the list */
LIBXSTREAM_CALL_INVALID,
/** collection of any valid flags from above */
LIBXSTREAM_CALL_DEFAULT = 0
} libxstream_call_flags;
/** Function argument type. */
LIBXSTREAM_EXPORT_C typedef struct LIBXSTREAM_TARGET(mic) libxstream_argument libxstream_argument;
/** Function type of an offloadable function. */
typedef void (/*LIBXSTREAM_CDECL*/*libxstream_function)(LIBXSTREAM_VARIADIC);
/** Query the number of available devices. */
LIBXSTREAM_EXPORT_C int libxstream_get_ndevices(size_t* ndevices);
/** Query the device set active for this thread. */
LIBXSTREAM_EXPORT_C int libxstream_get_active_device(int* device);
/** Set the active device for this thread. */
LIBXSTREAM_EXPORT_C int libxstream_set_active_device(int device);
/** Query the memory metrics of the device (valid to pass one NULL pointer). */
LIBXSTREAM_EXPORT_C int libxstream_mem_info(int device, size_t* allocatable, size_t* physical);
/** Query the real pointer on the device side; both pointers are equal if the device specifies the host. */
LIBXSTREAM_EXPORT_C int libxstream_mem_pointer(int device, const void* memory, const void** real);
/** Allocate aligned memory (0: automatic) on the device. */
LIBXSTREAM_EXPORT_C int libxstream_mem_allocate(int device, void** memory, size_t size, size_t alignment);
/** Deallocate memory; shall match the device where the memory was allocated. */
LIBXSTREAM_EXPORT_C int libxstream_mem_deallocate(int device, const void* memory);
/** Fill memory with zeros; allocated memory can carry an offset. */
LIBXSTREAM_EXPORT_C int libxstream_memset_zero(void* memory, size_t size, libxstream_stream* stream);
/** Copy memory from the host to the device; addresses can carry an offset. */
LIBXSTREAM_EXPORT_C int libxstream_memcpy_h2d(const void* host_mem, void* dev_mem, size_t size, libxstream_stream* stream);
/** Copy memory from the device to the host; addresses can carry an offset. */
LIBXSTREAM_EXPORT_C int libxstream_memcpy_d2h(const void* dev_mem, void* host_mem, size_t size, libxstream_stream* stream);
/** Copy memory from device to device; cross-device copies are allowed as well. */
LIBXSTREAM_EXPORT_C int libxstream_memcpy_d2d(const void* src, void* dst, size_t size, libxstream_stream* stream);
/** Query the range of valid priorities (inclusive bounds). */
LIBXSTREAM_EXPORT_C int libxstream_stream_priority_range(int* least, int* greatest);
/** Create a stream on a device (demux<0: auto-locks, 0: manual, demux>0: sync.). */
LIBXSTREAM_EXPORT_C int libxstream_stream_create(libxstream_stream** stream, int device, int demux, int priority, const char* name);
/** Destroy a stream; pending work must be completed if results are needed. */
LIBXSTREAM_EXPORT_C int libxstream_stream_destroy(const libxstream_stream* stream);
/** Wait for a stream to complete pending work; NULL to synchronize all streams. */
LIBXSTREAM_EXPORT_C int libxstream_stream_sync(libxstream_stream* stream);
/** Wait for an event inside the specified stream; a NULL-stream matches all streams. */
LIBXSTREAM_EXPORT_C int libxstream_stream_wait_event(const libxstream_stream* stream, const libxstream_event* event);
/** Lock a stream such that the caller thread can safely enqueue work. */
LIBXSTREAM_EXPORT_C int libxstream_stream_lock(libxstream_stream* stream);
/** Unlock a stream such that another thread can acquire the stream. */
LIBXSTREAM_EXPORT_C int libxstream_stream_unlock(libxstream_stream* stream);
/** Query the device the given stream is constructed for. */
LIBXSTREAM_EXPORT_C int libxstream_stream_device(const libxstream_stream* stream, int* device);
/** Query the device the given stream is constructed for. */
LIBXSTREAM_EXPORT_C int libxstream_stream_demux(const libxstream_stream* stream, int* demux);
/** Create an event; can be used multiple times to record an event. */
LIBXSTREAM_EXPORT_C int libxstream_event_create(libxstream_event** event);
/** Destroy an event; does not implicitly waits for the completion of the event. */
LIBXSTREAM_EXPORT_C int libxstream_event_destroy(const libxstream_event* event);
/** Record an event; an event can be re-recorded multiple times. */
LIBXSTREAM_EXPORT_C int libxstream_event_record(libxstream_event* event, libxstream_stream* stream);
/** Check whether an event has occurred or not (non-blocking). */
LIBXSTREAM_EXPORT_C int libxstream_event_query(const libxstream_event* event, libxstream_bool* occured);
/** Wait for an event to complete i.e., work queued prior to recording the event. */
LIBXSTREAM_EXPORT_C int libxstream_event_synchronize(libxstream_event* event);
/** Create a function signature with a certain maximum number of arguments. */
LIBXSTREAM_EXPORT_C int libxstream_fn_create_signature(libxstream_argument** signature, size_t nargs);
/** Destroy a function signature; does not release the bound data. */
LIBXSTREAM_EXPORT_C int libxstream_fn_destroy_signature(const libxstream_argument* signature);
/** Reset function signature allow reuse with a lesser amount of arguments (arity). */
LIBXSTREAM_EXPORT_C int libxstream_fn_clear_signature(libxstream_argument* signature);
/** Receive a temporary signature with a capacity of LIBXSTREAM_MAX_NARGS arguments; thread safe. */
LIBXSTREAM_EXPORT_C int libxstream_fn_signature(libxstream_argument** signature);
/** Construct an input argument; takes the device data, dimensionality, and shape. */
LIBXSTREAM_EXPORT_C int libxstream_fn_input(libxstream_argument* signature, size_t arg, const void* in, libxstream_type type, size_t dims, const size_t shape[]);
/** Construct an output argument; takes the device data, dimensionality, and shape. */
LIBXSTREAM_EXPORT_C int libxstream_fn_output(libxstream_argument* signature, size_t arg, void* out, libxstream_type type, size_t dims, const size_t shape[]);
/** Construct an in-out argument; takes the device data, dimensionality, and shape. */
LIBXSTREAM_EXPORT_C int libxstream_fn_inout(libxstream_argument* signature, size_t arg, void* inout, libxstream_type type, size_t dims, const size_t shape[]);
/** Query the maximum number of arguments that can be covered by the function signature. */
LIBXSTREAM_EXPORT_C int libxstream_fn_nargs(const libxstream_argument* signature, size_t* nargs);
/** Call a user function along with the signature; wait in case of a synchronous call. */
LIBXSTREAM_EXPORT_C int libxstream_fn_call(libxstream_function function, const libxstream_argument* signature, libxstream_stream* stream, int flags);
/** Query the size of the elemental type (Byte). */
LIBXSTREAM_EXPORT_C LIBXSTREAM_TARGET(mic) int libxstream_get_typesize(libxstream_type type, size_t* typesize);
/** Select a type according to the typesize; suiteable to transport the requested amount of Bytes. */
LIBXSTREAM_EXPORT_C LIBXSTREAM_TARGET(mic) int libxstream_get_autotype(size_t typesize, libxstream_type* autotype);
/** Query the name of the elemental type (string does not need to be buffered). */
LIBXSTREAM_EXPORT_C LIBXSTREAM_TARGET(mic) int libxstream_get_typename(libxstream_type type, const char** name);
/** Query the argument's 0-based position within the signature; needs a pointer variable (not from a by-value variable). */
LIBXSTREAM_EXPORT_C LIBXSTREAM_TARGET(mic) int libxstream_get_argument(const void* variable, size_t* arg);
/** Query the arity of the function signature (actual number of arguments). A NULL-signature designates the call context. */
LIBXSTREAM_EXPORT_C LIBXSTREAM_TARGET(mic) int libxstream_get_arity(const libxstream_argument* signature, size_t* arity);
/** Query the argument's data according to LIBXSTREAM_CALL_PPP convention. A NULL-signature designates the call context. */
LIBXSTREAM_EXPORT_C LIBXSTREAM_TARGET(mic) int libxstream_get_data(const libxstream_argument* signature, size_t arg, const void** data);
/** Query a textual representation; thread safe (valid until next call). A NULL-signature designates the call context. */
LIBXSTREAM_EXPORT_C LIBXSTREAM_TARGET(mic) int libxstream_get_string(const libxstream_argument* signature, size_t arg, const char** value);
/** Query the elemental type of the argument. A NULL-signature designates the call context. */
LIBXSTREAM_EXPORT_C LIBXSTREAM_TARGET(mic) int libxstream_get_type(const libxstream_argument* signature, size_t arg, libxstream_type* type);
/** Query the dimensionality of the argument; an elemental arg. is 0-dimensional. A NULL-signature designates the call context. */
LIBXSTREAM_EXPORT_C LIBXSTREAM_TARGET(mic) int libxstream_get_dims(const libxstream_argument* signature, size_t arg, size_t* dims);
/** Query the extent of the argument; an elemental argument has an 0-extent. A NULL-signature designates the call context. */
LIBXSTREAM_EXPORT_C LIBXSTREAM_TARGET(mic) int libxstream_get_shape(const libxstream_argument* signature, size_t arg, size_t shape[]);
/** Query the number of elements of the argument. A NULL-signature designates the call context. */
LIBXSTREAM_EXPORT_C LIBXSTREAM_TARGET(mic) int libxstream_get_size(const libxstream_argument* signature, size_t arg, size_t* size);
/** Query the size of the element type of the argument (Byte). A NULL-signature designates the call context. */
LIBXSTREAM_EXPORT_C LIBXSTREAM_TARGET(mic) int libxstream_get_elemsize(const libxstream_argument* signature, size_t arg, size_t* size);
/** Query the data size of the argument (Byte). A NULL-signature designates the call context. */
LIBXSTREAM_EXPORT_C LIBXSTREAM_TARGET(mic) int libxstream_get_datasize(const libxstream_argument* signature, size_t arg, size_t* size);
#if defined(__cplusplus)
template<typename TYPE> struct libxstream_map_to { static libxstream_type type() {/** select a type by type-size; bool goes here! */
libxstream_type autotype = LIBXSTREAM_TYPE_VOID; libxstream_get_autotype(sizeof(TYPE), &autotype); return autotype; } };
template<> struct libxstream_map_to<int8_t> { static libxstream_type type() { return LIBXSTREAM_TYPE_I8; } };
template<> struct libxstream_map_to<uint8_t> { static libxstream_type type() { return LIBXSTREAM_TYPE_U8; } };
template<> struct libxstream_map_to<int16_t> { static libxstream_type type() { return LIBXSTREAM_TYPE_I16; } };
template<> struct libxstream_map_to<uint16_t> { static libxstream_type type() { return LIBXSTREAM_TYPE_U16; } };
template<> struct libxstream_map_to<int32_t> { static libxstream_type type() { return LIBXSTREAM_TYPE_I32; } };
template<> struct libxstream_map_to<uint32_t> { static libxstream_type type() { return LIBXSTREAM_TYPE_U32; } };
template<> struct libxstream_map_to<int64_t> { static libxstream_type type() { return LIBXSTREAM_TYPE_I64; } };
template<> struct libxstream_map_to<uint64_t> { static libxstream_type type() { return LIBXSTREAM_TYPE_U64; } };
template<> struct libxstream_map_to<float> { static libxstream_type type() { return LIBXSTREAM_TYPE_F32; } };
template<> struct libxstream_map_to<double> { static libxstream_type type() { return LIBXSTREAM_TYPE_F64; } };
template<> struct libxstream_map_to<float[2]> { static libxstream_type type() { return LIBXSTREAM_TYPE_C32; } };
template<> struct libxstream_map_to<double[2]> { static libxstream_type type() { return LIBXSTREAM_TYPE_C64; } };
template<> struct libxstream_map_to<std::complex<float> > { static libxstream_type type() { return LIBXSTREAM_TYPE_C32; } };
template<> struct libxstream_map_to<std::complex<double> > { static libxstream_type type() { return LIBXSTREAM_TYPE_C64; } };
template<> struct libxstream_map_to<char> { static libxstream_type type() { return LIBXSTREAM_TYPE_CHAR; } };
template<> struct libxstream_map_to<void> { static libxstream_type type() { return LIBXSTREAM_TYPE_VOID; } };
template<typename TYPE> struct libxstream_map_to<TYPE*> { static libxstream_type type() { return libxstream_map_to<TYPE>::type(); } };
template<typename TYPE> struct libxstream_map_to<const TYPE*> { static libxstream_type type() { return libxstream_map_to<TYPE>::type(); } };
template<typename TYPE> struct libxstream_map_to<TYPE**> { static libxstream_type type() { return libxstream_map_to<uintptr_t>::type(); } };
template<typename TYPE> struct libxstream_map_to<const TYPE**> { static libxstream_type type() { return libxstream_map_to<uintptr_t>::type(); } };
template<typename TYPE> struct libxstream_map_to<TYPE*const*> { static libxstream_type type() { return libxstream_map_to<uintptr_t>::type(); } };
template<typename TYPE> struct libxstream_map_to<const TYPE*const*> { static libxstream_type type() { return libxstream_map_to<uintptr_t>::type(); } };
template<typename TYPE> libxstream_type libxstream_map_to_type(const TYPE&) { return libxstream_map_to<TYPE>::type(); }
template<typename TYPE> libxstream_type libxstream_map_to_type(TYPE*) { return libxstream_map_to<TYPE*>::type(); }
template<typename TYPE> libxstream_type libxstream_map_to_type(const TYPE*) { return libxstream_map_to<const TYPE*>::type(); }
template<typename TYPE> libxstream_type libxstream_map_to_type(TYPE**) { return libxstream_map_to<TYPE**>::type(); }
template<typename TYPE> libxstream_type libxstream_map_to_type(const TYPE**) { return libxstream_map_to<const TYPE**>::type(); }
template<typename TYPE> libxstream_type libxstream_map_to_type(TYPE*const*) { return libxstream_map_to<TYPE*const*>::type(); }
template<typename TYPE> libxstream_type libxstream_map_to_type(const TYPE*const*) { return libxstream_map_to<const TYPE*const*>::type(); }
template<libxstream_type VALUE> struct libxstream_map_from { /** compile-time error expected */ };
template<> struct libxstream_map_from<LIBXSTREAM_TYPE_I8> { typedef int8_t type; };
template<> struct libxstream_map_from<LIBXSTREAM_TYPE_U8> { typedef uint8_t type; };
template<> struct libxstream_map_from<LIBXSTREAM_TYPE_I16> { typedef int16_t type; };
template<> struct libxstream_map_from<LIBXSTREAM_TYPE_U16> { typedef uint16_t type; };
template<> struct libxstream_map_from<LIBXSTREAM_TYPE_I32> { typedef int32_t type; };
template<> struct libxstream_map_from<LIBXSTREAM_TYPE_U32> { typedef uint32_t type; };
template<> struct libxstream_map_from<LIBXSTREAM_TYPE_I64> { typedef int64_t type; };
template<> struct libxstream_map_from<LIBXSTREAM_TYPE_U64> { typedef uint64_t type; };
template<> struct libxstream_map_from<LIBXSTREAM_TYPE_F32> { typedef float type; };
template<> struct libxstream_map_from<LIBXSTREAM_TYPE_F64> { typedef double type; };
template<> struct libxstream_map_from<LIBXSTREAM_TYPE_C32> { typedef std::complex<float> type; typedef float ctype[2]; };
template<> struct libxstream_map_from<LIBXSTREAM_TYPE_C64> { typedef std::complex<double> type; typedef double ctype[2]; };
template<> struct libxstream_map_from<LIBXSTREAM_TYPE_CHAR> { typedef char type; };
template<> struct libxstream_map_from<LIBXSTREAM_TYPE_VOID> { typedef void type; };
#endif /*__cplusplus*/
#endif /*LIBXSTREAM_H*/

View file

@ -1,37 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#ifndef LIBXSTREAM_H
# include "libxstream.h"
#endif
#if defined(LIBXSTREAM_OFFLOAD)
# pragma offload_attribute(push,target(mic))
#endif

View file

@ -1,165 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#ifndef LIBXSTREAM_CONFIG_H
#define LIBXSTREAM_CONFIG_H
#ifndef LIBXSTREAM_MACROS_H
# error Do not include <libxstream_config.h> directly (use <libxstream_macros.h>)!
#endif
#if !defined(LIBXSTREAM_CONFIG_EXTERNAL)
/**
* Debug-time error checks are usually disabled for production code (NDEBUG).
* The LIBXSTREAM_DEBUG symbol ultimately controls this (see libxstream_macros.h).
*/
#define LIBXSTREAM_ERROR_DEBUG
/**
* Runtime error checks and error handling code is usually enabled.
* The LIBXSTREAM_CHECK symbol ultimately controls this (see libxstream_macros.h).
*/
#define LIBXSTREAM_ERROR_CHECK
/**
* Enables printing trace information.
* Valid selections:
* - #define LIBXSTREAM_TRACE: enables default (1) behavior
* - #define LIBXSTREAM_TRACE 0: disables trace information
* - #define LIBXSTREAM_TRACE 1: enabled for debug builds
* - #define LIBXSTREAM_TRACE 2: enabled
*/
#define LIBXSTREAM_TRACE
/**
* Enables asynchronous offloads.
* Valid selections:
* - #define LIBXSTREAM_ASYNC: enables default (1) behavior
* - #define LIBXSTREAM_ASYNC 0: synchronous offloads
* - #define LIBXSTREAM_ASYNC 1: compiler offload
* - #define LIBXSTREAM_ASYNC 2: compiler streams
* - #define LIBXSTREAM_ASYNC 3: native (KNL) - not implemented yet / must be disabled
*/
#define LIBXSTREAM_ASYNC 0
/** Not implemented yet. Must be disabled. */
/*#define LIBXSTREAM_ASYNCHOST*/
/** Not implemented yet. Must be disabled. */
/*#define LIBXSTREAM_ALLOC_PINNED*/
/** SIMD width in Byte (actual alignment might be smaller). */
#define LIBXSTREAM_MAX_SIMD 64
/** Alignment in Byte (actual alignment might be smaller). */
#define LIBXSTREAM_MAX_ALIGN (2 * 1024 * 1024)
/** Maximum number of devices. */
#define LIBXSTREAM_MAX_NDEVICES 8
/** Maximum number of streams per device. */
#define LIBXSTREAM_MAX_NSTREAMS 32
/** Maximum dimensionality of arrays. */
#define LIBXSTREAM_MAX_NDIMS 4
/** Maximum number of arguments in offload structure. */
#define LIBXSTREAM_MAX_NARGS 16
/** Maximum number of executions in the queue. */
#define LIBXSTREAM_MAX_QSIZE 1024
/** Maximum number of host threads. */
#define LIBXSTREAM_MAX_NTHREADS 1024
/**
* Number of times a locked stream must be discovered to be
* "not alive" before unlocking the stream in question.
*/
#define LIBXSTREAM_LOCK_RETRY 3
/** Enables non-recursive locks. */
#define LIBXSTREAM_LOCK_NONRECURSIVE
/** Number of milliseconds a lock can stall. */
#define LIBXSTREAM_WAIT_LOCK_MS 200
/** Number of cycles to actively wait. */
#define LIBXSTREAM_WAIT_ACTIVE_CYCLES 10000
/**
* Thread-local signals allow for some more concurrency
* when forming the signal/wait dependency chain.
*/
/*#define LIBXSTREAM_THREADLOCAL_SIGNALS*/
/** Instructs the library to wait for each enqueued work item. */
/*#define LIBXSTREAM_SYNCHRONOUS*/
/** Synchronize on memory allocation/deallocation events. */
/*#define LIBXSTREAM_SYNCMEM*/
/** Prefers OpenMP based locking primitives. */
/*#define LIBXSTREAM_PREFER_OPENMP*/
/**
* Changing the calling convention; this is a rather deep switch impacting
* all function definitions of functions able to get enqueued. The default
* convention is "by-pointer" passing arrays, scalars, and complex values
* by pointer. Enabling the "by-value" convention attempts to pass arrays
* and complex values by pointer whereas scalars smaller are passed by
* value. The "by-value" convention is not completely functional and
* cannot be used.
*/
/*#define LIBXSTREAM_CALL_BYVALUE*/
/**
* Below preprocessor symbols fixup some platform specifics.
*/
#if !defined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES)
# define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#endif
#if !defined(_CRT_SECURE_NO_DEPRECATE)
# define _CRT_SECURE_NO_DEPRECATE 1
#endif
#if !defined(_USE_MATH_DEFINES)
# define _USE_MATH_DEFINES 1
#endif
#if !defined(WIN32_LEAN_AND_MEAN)
# define WIN32_LEAN_AND_MEAN 1
#endif
#if !defined(NOMINMAX)
# define NOMINMAX 1
#endif
#endif /*LIBXSTREAM_CONFIG_EXTERNAL*/
#endif /*LIBXSTREAM_CONFIG_H*/

View file

@ -1,33 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#if defined(LIBXSTREAM_OFFLOAD)
# pragma offload_attribute(pop)
#endif

View file

@ -1,254 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#ifndef LIBXSTREAM_MACROS_H
#define LIBXSTREAM_MACROS_H
#include "libxstream_config.h"
#if !defined(LIBXSTREAM_PREFER_OPENMP) || !defined(_OPENMP)
# if (201103L <= __cplusplus)
# if !defined(LIBXSTREAM_STDFEATURES)
# define LIBXSTREAM_STDFEATURES
# endif
# if !defined(LIBXSTREAM_STDFEATURES_THREADX) && !defined(__MIC__)
# define LIBXSTREAM_STDFEATURES_THREADX
# endif
# elif (1600 < _MSC_VER)
# if !defined(LIBXSTREAM_STDFEATURES)
# define LIBXSTREAM_STDFEATURES
# endif
# if !defined(LIBXSTREAM_STDFEATURES_THREADX)
# define LIBXSTREAM_STDFEATURES_THREADX
# endif
# elif ((4 <= __GNUC__ && 5 <= __GNUC_MINOR__) && (1L == __cplusplus)) || (defined(__INTEL_COMPILER) && defined(__GXX_EXPERIMENTAL_CXX0X__))
# if !defined(LIBXSTREAM_STDFEATURES)
# define LIBXSTREAM_STDFEATURES
# endif
# endif
#endif
#if defined(_WIN32) && !defined(__GNUC__)
# define LIBXSTREAM_ATTRIBUTE(A) __declspec(A)
# define LIBXSTREAM_ALIGNED(DECL, N) LIBXSTREAM_ATTRIBUTE(align(N)) DECL
# define LIBXSTREAM_CDECL __cdecl
#elif defined(__GNUC__)
# define LIBXSTREAM_ATTRIBUTE(A) __attribute__((A))
# define LIBXSTREAM_ALIGNED(DECL, N) DECL LIBXSTREAM_ATTRIBUTE(aligned(N))
# define LIBXSTREAM_CDECL LIBXSTREAM_ATTRIBUTE(cdecl)
#endif
#define LIBXSTREAM_ALIGN(A, ALIGNMENT) ((uintptr_t)(-(-((intptr_t)A) & -((intptr_t)(ALIGNMENT)))))
#if defined(_WIN32) && !defined(__GNUC__)
# define LIBXSTREAM_TLS LIBXSTREAM_ATTRIBUTE(thread)
#elif defined(__GNUC__)
# define LIBXSTREAM_TLS __thread
#elif defined(LIBXSTREAM_STDFEATURES)
# define LIBXSTREAM_TLS thread_local
#endif
#if !defined(LIBXSTREAM_TLS)
# define LIBXSTREAM_TLS
#endif
#define LIBXSTREAM_TOSTRING_AUX(SYMBOL) #SYMBOL
#define LIBXSTREAM_TOSTRING(SYMBOL) LIBXSTREAM_TOSTRING_AUX(SYMBOL)
#if defined(__INTEL_COMPILER)
# define LIBXSTREAM_ASSUME_ALIGNED(A, N) __assume_aligned(A, N)
# define LIBXSTREAM_PRAGMA(DIRECTIVE) __pragma(DIRECTIVE)
#elif (199901L <= __STDC_VERSION__)
# define LIBXSTREAM_ASSUME_ALIGNED(A, N)
# define LIBXSTREAM_PRAGMA(DIRECTIVE) _Pragma(LIBXSTREAM_STRINGIFY(DIRECTIVE))
#elif defined(_MSC_VER)
# define LIBXSTREAM_ASSUME_ALIGNED(A, N)
# define LIBXSTREAM_PRAGMA(DIRECTIVE) __pragma(DIRECTIVE)
#else
# define LIBXSTREAM_ASSUME_ALIGNED(A, N)
# define LIBXSTREAM_PRAGMA(DIRECTIVE)
#endif
#if defined(__INTEL_OFFLOAD) && (!defined(_WIN32) || (1400 <= __INTEL_COMPILER))
# define LIBXSTREAM_OFFLOAD 1
# define LIBXSTREAM_TARGET(A) LIBXSTREAM_ATTRIBUTE(target(A))
#else
/*# define LIBXSTREAM_OFFLOAD 0*/
# define LIBXSTREAM_TARGET(A)
#endif
#define LIBXSTREAM_IMPORT_DLL __declspec(dllimport)
#if defined(_WINDLL) && defined(_WIN32)
# if defined(LIBXSTREAM_EXPORTED)
# define LIBXSTREAM_EXPORT __declspec(dllexport)
# else
# define LIBXSTREAM_EXPORT LIBXSTREAM_IMPORT_DLL
# endif
#else
# define LIBXSTREAM_EXPORT
#endif
#if defined(__cplusplus)
# define LIBXSTREAM_EXTERN_C extern "C"
# define LIBXSTREAM_EXPORT_C LIBXSTREAM_EXTERN_C LIBXSTREAM_EXPORT
# define LIBXSTREAM_VARIADIC ...
#else
# define LIBXSTREAM_EXTERN_C
# define LIBXSTREAM_EXPORT_C LIBXSTREAM_EXPORT
# define LIBXSTREAM_VARIADIC
#endif /*__cplusplus*/
#if defined(__GNUC__) && !defined(_WIN32) && !defined(__CYGWIN32__)
# define LIBXSTREAM_RESTRICT __restrict__
#elif defined(_MSC_VER)
# define LIBXSTREAM_RESTRICT __restrict
#else
# define LIBXSTREAM_RESTRICT
#endif
#if (defined(LIBXSTREAM_ERROR_DEBUG) || defined(_DEBUG)) && !defined(NDEBUG) && !defined(LIBXSTREAM_DEBUG)
# define LIBXSTREAM_DEBUG
#endif
#if defined(LIBXSTREAM_ERROR_CHECK) && !defined(LIBXSTREAM_CHECK)
# define LIBXSTREAM_CHECK
#endif
LIBXSTREAM_EXPORT_C LIBXSTREAM_TARGET(mic) void libxstream_use_sink(const void*);
LIBXSTREAM_EXPORT_C LIBXSTREAM_TARGET(mic) int libxstream_not_constant(int value);
#if defined(LIBXSTREAM_DEBUG)
# define LIBXSTREAM_USE_SINK(VAR) libxstream_use_sink(VAR)
# define LIBXSTREAM_ASSERT(A) assert(A)
# include "libxstream_begin.h"
# include <assert.h>
# include "libxstream_end.h"
#else
# define LIBXSTREAM_USE_SINK(VAR)
# define LIBXSTREAM_ASSERT(A)
#endif
#define LIBXSTREAM_TRUE 1
#define LIBXSTREAM_FALSE 0
#define LIBXSTREAM_ERROR_NONE 0
#define LIBXSTREAM_ERROR_RUNTIME -1
#define LIBXSTREAM_ERROR_CONDITION -2
#if defined(LIBXSTREAM_TRACE) && ((1 == ((2*LIBXSTREAM_TRACE+1)/2) && defined(LIBXSTREAM_DEBUG)) || 1 < ((2*LIBXSTREAM_TRACE+1)/2))
# define LIBXSTREAM_PRINT
# define LIBXSTREAM_PRINT_INFO(MESSAGE, ...) fprintf(stderr, "DBG " MESSAGE "\n", __VA_ARGS__)
# define LIBXSTREAM_PRINT_INFO0(MESSAGE) fprintf(stderr, "DBG " MESSAGE "\n")
# define LIBXSTREAM_PRINT_INFOCTX(MESSAGE, ...) fprintf(stderr, "DBG %s: " MESSAGE "\n", __FUNCTION__, __VA_ARGS__)
# define LIBXSTREAM_PRINT_INFOCTX0(MESSAGE) fprintf(stderr, "DBG %s: " MESSAGE "\n", __FUNCTION__)
# define LIBXSTREAM_PRINT_WARN(MESSAGE, ...) fprintf(stderr, "WRN " MESSAGE "\n", __VA_ARGS__)
# define LIBXSTREAM_PRINT_WARN0(MESSAGE) fprintf(stderr, "WRN " MESSAGE "\n")
# define LIBXSTREAM_PRINT_WARNCTX(MESSAGE, ...) fprintf(stderr, "WRN %s: " MESSAGE "\n", __FUNCTION__, __VA_ARGS__)
# define LIBXSTREAM_PRINT_WARNCTX0(MESSAGE) fprintf(stderr, "WRN %s: " MESSAGE "\n", __FUNCTION__)
#else
# define LIBXSTREAM_PRINT_INFO(MESSAGE, ...)
# define LIBXSTREAM_PRINT_INFO0(MESSAGE)
# define LIBXSTREAM_PRINT_INFOCTX(MESSAGE, ...)
# define LIBXSTREAM_PRINT_INFOCTX0(MESSAGE)
# define LIBXSTREAM_PRINT_WARN(MESSAGE, ...)
# define LIBXSTREAM_PRINT_WARN0(MESSAGE)
# define LIBXSTREAM_PRINT_WARNCTX(MESSAGE, ...)
# define LIBXSTREAM_PRINT_WARNCTX0(MESSAGE)
#endif
#if defined(_MSC_VER)
# define LIBXSTREAM_SNPRINTF(S, N, F, ...) _snprintf_s(S, N, _TRUNCATE, F, __VA_ARGS__)
#else
# define LIBXSTREAM_SNPRINTF(S, N, F, ...) snprintf(S, N, F, __VA_ARGS__)
#endif
#define LIBXSTREAM_MIN(A, B) ((A) < (B) ? (A) : (B))
#define LIBXSTREAM_MAX(A, B) ((A) < (B) ? (B) : (A))
#if defined(LIBXSTREAM_CHECK)
# define LIBXSTREAM_CHECK_ERROR(RETURN_VALUE) if (LIBXSTREAM_ERROR_NONE != (RETURN_VALUE)) return RETURN_VALUE
# define LIBXSTREAM_CHECK_CONDITION(CONDITION) if (!(CONDITION)) return LIBXSTREAM_ERROR_CONDITION
# define LIBXSTREAM_CHECK_CONDITION_RETURN(CONDITION) if (!(CONDITION)) return
# define LIBXSTREAM_CHECK_CALL_RETURN(EXPRESSION) if (LIBXSTREAM_ERROR_NONE != (EXPRESSION)) return
# if defined(__cplusplus)
# define LIBXSTREAM_CHECK_CALL_THROW(EXPRESSION) if (LIBXSTREAM_ERROR_NONE != (EXPRESSION)) throw std::runtime_error(LIBXSTREAM_TOSTRING(EXPRESSION) " at " __FILE__ ":" LIBXSTREAM_TOSTRING(__LINE__))
# define LIBXSTREAM_CHECK_CONDITION_THROW(CONDITION) if (!(CONDITION)) throw std::runtime_error(LIBXSTREAM_TOSTRING(CONDITION) " at " __FILE__ ":" LIBXSTREAM_TOSTRING(__LINE__))
# else
# define LIBXSTREAM_CHECK_CALL_THROW(EXPRESSION) do { int result = (EXPRESSION); if (LIBXSTREAM_ERROR_NONE != result) abort(result); } while(libxstream_not_constant(LIBXSTREAM_FALSE))
# define LIBXSTREAM_CHECK_CONDITION_THROW(CONDITION) if (!(CONDITION)) abort(1)
# endif
# if defined(_OPENMP)
# if defined(LIBXSTREAM_DEBUG)
# define LIBXSTREAM_CHECK_CALL(EXPRESSION) LIBXSTREAM_ASSERT(LIBXSTREAM_ERROR_NONE == (EXPRESSION))
# else
# define LIBXSTREAM_CHECK_CALL(EXPRESSION) (EXPRESSION)
# endif
# else
# define LIBXSTREAM_CHECK_CALL(EXPRESSION) do { int result = (EXPRESSION); if (LIBXSTREAM_ERROR_NONE != result) return result; } while(libxstream_not_constant(LIBXSTREAM_FALSE))
# endif
#elif defined(LIBXSTREAM_DEBUG)
# define LIBXSTREAM_CHECK_ERROR(RETURN_VALUE) LIBXSTREAM_ASSERT(LIBXSTREAM_ERROR_NONE == (RETURN_VALUE))
# define LIBXSTREAM_CHECK_CONDITION(CONDITION) LIBXSTREAM_ASSERT(CONDITION)
# define LIBXSTREAM_CHECK_CONDITION_RETURN(CONDITION) LIBXSTREAM_ASSERT(CONDITION)
# define LIBXSTREAM_CHECK_CONDITION_THROW(CONDITION) LIBXSTREAM_ASSERT(CONDITION)
# define LIBXSTREAM_CHECK_CALL_RETURN(EXPRESSION) LIBXSTREAM_ASSERT(LIBXSTREAM_ERROR_NONE == (EXPRESSION))
# define LIBXSTREAM_CHECK_CALL_THROW(EXPRESSION) LIBXSTREAM_ASSERT(LIBXSTREAM_ERROR_NONE == (EXPRESSION))
# define LIBXSTREAM_CHECK_CALL(EXPRESSION) LIBXSTREAM_ASSERT(LIBXSTREAM_ERROR_NONE == (EXPRESSION))
#else
# define LIBXSTREAM_CHECK_ERROR(RETURN_VALUE) LIBXSTREAM_ASSERT(LIBXSTREAM_ERROR_NONE == (RETURN_VALUE))
# define LIBXSTREAM_CHECK_CONDITION(CONDITION) LIBXSTREAM_ASSERT(CONDITION)
# define LIBXSTREAM_CHECK_CONDITION_RETURN(CONDITION) LIBXSTREAM_ASSERT(CONDITION)
# define LIBXSTREAM_CHECK_CONDITION_THROW(CONDITION) LIBXSTREAM_ASSERT(CONDITION)
# define LIBXSTREAM_CHECK_CALL_RETURN(EXPRESSION) EXPRESSION
# define LIBXSTREAM_CHECK_CALL_THROW(EXPRESSION) EXPRESSION
# define LIBXSTREAM_CHECK_CALL(EXPRESSION) EXPRESSION
#endif
#if defined(LIBXSTREAM_DEBUG)
# define LIBXSTREAM_CHECK_CALL_ASSERT(EXPRESSION) LIBXSTREAM_ASSERT(LIBXSTREAM_ERROR_NONE == (EXPRESSION))
#else
# define LIBXSTREAM_CHECK_CALL_ASSERT(EXPRESSION) EXPRESSION
#endif
#if defined(LIBXSTREAM_CALL_BYVALUE)
# define LIBXSTREAM_INVAL(TYPE) TYPE
# define LIBXSTREAM_GETVAL(VALUE) VALUE
# define LIBXSTREAM_SETVAL(VALUE) VALUE
#else /*by-pointer*/
# if defined(__cplusplus)
# define LIBXSTREAM_INVAL(TYPE) const TYPE&
# define LIBXSTREAM_GETVAL(VALUE) VALUE
# define LIBXSTREAM_SETVAL(VALUE) VALUE
# else
# define LIBXSTREAM_INVAL(TYPE) const TYPE*
# define LIBXSTREAM_GETVAL(VALUE) *VALUE
# define LIBXSTREAM_SETVAL(VALUE) &VALUE
# endif
#endif
#endif /*LIBXSTREAM_MACROS_H*/

View file

@ -1,4 +0,0 @@
{
"description": "LIBXSMM Sample Code",
"requires": ["../../include"]
}

View file

@ -1,27 +0,0 @@
#!/bin/bash
#TRY="echo"
FILE="benchmark.txt"
STREAMS=2
SIZE=250
STRIDE=1
FRACT=8
if [ "" != "$1" ] ; then
SIZE=$1
shift
fi
if [ "" != "$1" ] ; then
STRIDE=$1
shift
fi
BSIZE=$((SIZE / FRACT))
BATCH=${STRIDE}
cat /dev/null > ${FILE}
while [[ ${BATCH} -le ${BSIZE} ]] ; do
${TRY} ./multi-dgemm.sh ${SIZE} ${BATCH} $* >> ${FILE}
BATCH=$((BATCH + STRIDE))
done

View file

@ -1,217 +0,0 @@
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 64.0 MB
Running 250 batches of 1 item...
Performance: 83.9 GFLOPS/s (synchronization)
Duration: 4.1 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 128.0 MB
Running 125 batches of 2 items...
Performance: 119.2 GFLOPS/s (synchronization)
Duration: 2.9 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 192.0 MB
Running 84 batches of 3 items...
Performance: 124.7 GFLOPS/s (synchronization)
Duration: 2.8 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 256.0 MB
Running 63 batches of 4 items...
Performance: 126.4 GFLOPS/s (synchronization)
Duration: 2.8 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 320.0 MB
Running 50 batches of 5 items...
Performance: 148.4 GFLOPS/s (synchronization)
Duration: 2.3 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 384.0 MB
Running 42 batches of 6 items...
Performance: 132.8 GFLOPS/s (synchronization)
Duration: 2.6 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 448.0 MB
Running 36 batches of 7 items...
Performance: 146.0 GFLOPS/s (synchronization)
Duration: 2.4 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 512.0 MB
Running 32 batches of 8 items...
Performance: 145.1 GFLOPS/s (synchronization)
Duration: 2.4 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 576.0 MB
Running 28 batches of 9 items...
Performance: 142.3 GFLOPS/s (synchronization)
Duration: 2.4 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 640.0 MB
Running 25 batches of 10 items...
Performance: 144.7 GFLOPS/s (synchronization)
Duration: 2.4 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 704.0 MB
Running 23 batches of 11 items...
Performance: 136.9 GFLOPS/s (synchronization)
Duration: 2.5 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 768.0 MB
Running 21 batches of 12 items...
Performance: 140.4 GFLOPS/s (synchronization)
Duration: 2.5 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 832.0 MB
Running 20 batches of 13 items...
Performance: 131.1 GFLOPS/s (synchronization)
Duration: 2.7 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 896.0 MB
Running 18 batches of 14 items...
Performance: 138.0 GFLOPS/s (synchronization)
Duration: 2.5 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 960.0 MB
Running 17 batches of 15 items...
Performance: 136.5 GFLOPS/s (synchronization)
Duration: 2.6 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 1024.0 MB
Running 16 batches of 16 items...
Performance: 130.4 GFLOPS/s (synchronization)
Duration: 2.7 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 1088.0 MB
Running 15 batches of 17 items...
Performance: 132.8 GFLOPS/s (synchronization)
Duration: 2.6 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 1152.0 MB
Running 14 batches of 18 items...
Performance: 127.2 GFLOPS/s (synchronization)
Duration: 2.7 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 1216.0 MB
Running 14 batches of 19 items...
Performance: 125.7 GFLOPS/s (synchronization)
Duration: 2.8 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 1280.0 MB
Running 13 batches of 20 items...
Performance: 128.4 GFLOPS/s (synchronization)
Duration: 2.7 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 1344.0 MB
Running 12 batches of 21 items...
Performance: 113.3 GFLOPS/s (synchronization)
Duration: 3.1 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 1408.0 MB
Running 12 batches of 22 items...
Performance: 124.4 GFLOPS/s (synchronization)
Duration: 2.8 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 1472.0 MB
Running 11 batches of 23 items...
Performance: 113.2 GFLOPS/s (synchronization)
Duration: 3.1 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 1536.0 MB
Running 11 batches of 24 items...
Performance: 115.3 GFLOPS/s (synchronization)
Duration: 3.0 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 1600.0 MB
Running 10 batches of 25 items...
Performance: 115.2 GFLOPS/s (synchronization)
Duration: 3.0 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 1664.0 MB
Running 10 batches of 26 items...
Performance: 119.2 GFLOPS/s (synchronization)
Duration: 2.9 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 1728.0 MB
Running 10 batches of 27 items...
Performance: 114.1 GFLOPS/s (synchronization)
Duration: 3.1 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 1792.0 MB
Running 9 batches of 28 items...
Performance: 117.0 GFLOPS/s (synchronization)
Duration: 3.0 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 1856.0 MB
Running 9 batches of 29 items...
Performance: 114.9 GFLOPS/s (synchronization)
Duration: 3.0 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 1920.0 MB
Running 9 batches of 30 items...
Performance: 120.1 GFLOPS/s (synchronization)
Duration: 2.9 s
Error: 1.13687e-13
Finished
Initializing 1 device and host data... 4435.7 MB
Initializing 2 streams per device... 1984.0 MB
Running 9 batches of 31 items...
Performance: 117.5 GFLOPS/s (synchronization)
Duration: 3.0 s
Error: 1.13687e-13
Finished

View file

@ -1,46 +0,0 @@
#!/bin/bash
LIBXSTREAM_ROOT="../.."
NAME=$(basename ${PWD})
ICCOPT="-O2 -xHost -ansi-alias -offload-option,mic,compiler,\"-L${MKLROOT}/lib/mic\""
ICCLNK="-mkl"
GCCOPT="-O2 -march=native"
GCCLNK="-llapack -lblas"
OPT="-Wall -std=c++0x"
if [[ "" = "${CXX}" ]] ; then
CXX=$(which icpc 2> /dev/null)
if [[ "" != "${CXX}" ]] ; then
OPT+=" ${ICCOPT}"
LNK+=" ${ICCLNK}"
else
CXX="g++"
OPT+=" ${GCCOPT}"
LNK+=" ${GCCLNK}"
fi
else
OPT+=" ${GCCOPT}"
LNK+=" ${GCCLNK}"
fi
if [ "-g" = "$1" ] ; then
OPT+=" -O0 -g"
shift
else
OPT+=" -DNDEBUG"
fi
if [[ "Windows_NT" = "${OS}" ]] ; then
OPT+=" -D_REENTRANT"
LNK+=" -lpthread"
else
OPT+=" -pthread"
fi
${CXX} ${OPT} $* \
-I${LIBXSTREAM_ROOT}/include -I${LIBXSTREAM_ROOT}/src -DLIBXSTREAM_EXPORTED \
${LIBXSTREAM_ROOT}/src/*.cpp *.cpp \
${LNK} -o ${NAME}

View file

@ -1,246 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#include "multi-dgemm-type.hpp"
#include "../../include/libxstream_begin.h"
#include <stdexcept>
#include <algorithm>
#include <cstdlib>
#include "../../include/libxstream_end.h"
multi_dgemm_type::host_data_type::host_data_type(libxstream_function process, size_t size, const size_t split[])
: m_process(process)
, m_adata(0), m_bdata(0), m_cdata(0), m_idata(0)
, m_size(size), m_flops(0)
{
LIBXSTREAM_CHECK_CALL_THROW(libxstream_mem_allocate(-1, reinterpret_cast<void**>(&m_idata), sizeof(size_t) * (size + 1), 0));
size_t isize = split[0];
size_t msize = 0, n = 100, nn = n * n;
for (size_t i = 0; i < isize; ++i) {
m_flops += nn * (2 * n + 1);
m_idata[i] = msize;
msize += nn;
}
isize += split[1];
n = 600, nn = n * n;
for (size_t i = split[0]; i < isize; ++i) {
m_flops += nn * (2 * n + 1);
m_idata[i] = msize;
msize += nn;
}
n = 1000, nn = n * n;
for (size_t i = isize; i < size; ++i) {
m_flops += nn * (2 * n + 1);
m_idata[i] = msize;
msize += nn;
}
m_idata[size] = msize;
LIBXSTREAM_CHECK_CALL_THROW(libxstream_mem_allocate(-1, reinterpret_cast<void**>(&m_adata), sizeof(double) * msize, 0));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_mem_allocate(-1, reinterpret_cast<void**>(&m_bdata), sizeof(double) * msize, 0));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_mem_allocate(-1, reinterpret_cast<void**>(&m_cdata), sizeof(double) * msize, 0));
static const double scale = 1.0 / RAND_MAX;
for (size_t i = 0; i < msize; ++i) {
m_adata[i] = scale * (2 * std::rand() - RAND_MAX);
m_bdata[i] = scale * (2 * std::rand() - RAND_MAX);
m_cdata[i] = 0;
}
}
multi_dgemm_type::host_data_type::~host_data_type()
{
/*LIBXSTREAM_CHECK_CALL_THROW*/(libxstream_mem_deallocate(-1, m_adata));
/*LIBXSTREAM_CHECK_CALL_THROW*/(libxstream_mem_deallocate(-1, m_bdata));
/*LIBXSTREAM_CHECK_CALL_THROW*/(libxstream_mem_deallocate(-1, m_cdata));
/*LIBXSTREAM_CHECK_CALL_THROW*/(libxstream_mem_deallocate(-1, m_idata));
}
size_t multi_dgemm_type::host_data_type::max_matrix_size() const
{
LIBXSTREAM_ASSERT(0 == m_size || 0 == m_idata[0]);
size_t result = 0, i0 = 0;
for (size_t i = 0; i < m_size; ++i) {
const size_t i1 = m_idata[i+1];
result = std::max(result, i1 - i0);
i0 = i1;
}
return result;
}
size_t multi_dgemm_type::host_data_type::bytes() const
{
return sizeof(double) * m_idata[m_size] * 3 + sizeof(size_t) * m_size;
}
bool multi_dgemm_type::host_data_type::ready() const
{
LIBXSTREAM_ASSERT(0 == m_process || (m_adata && m_bdata && m_cdata && m_idata));
return 0 != m_process;
}
multi_dgemm_type::multi_dgemm_type()
: m_host_data(0), m_signature(0), m_stream(0), m_event(0)
, m_adata(0), m_bdata(0), m_cdata(0)
, m_idata(0), m_max_batch(0)
{}
multi_dgemm_type::~multi_dgemm_type()
{
/*LIBXSTREAM_CHECK_CALL_THROW*/(deinit());
}
int multi_dgemm_type::deinit()
{
if (m_host_data) {
int device = -1;
LIBXSTREAM_CHECK_CALL(libxstream_stream_device(m_stream, &device));
LIBXSTREAM_CHECK_CALL(libxstream_fn_destroy_signature(m_signature));
LIBXSTREAM_CHECK_CALL(libxstream_stream_destroy(m_stream));
LIBXSTREAM_CHECK_CALL(libxstream_event_destroy(m_event));
LIBXSTREAM_CHECK_CALL(libxstream_mem_deallocate(device, m_adata));
LIBXSTREAM_CHECK_CALL(libxstream_mem_deallocate(device, m_bdata));
LIBXSTREAM_CHECK_CALL(libxstream_mem_deallocate(device, m_cdata));
LIBXSTREAM_CHECK_CALL(libxstream_mem_deallocate(device, m_idata));
m_host_data = 0;
#if defined(LIBXSTREAM_DEBUG)
m_max_batch = 0;
m_signature = 0;
m_stream = 0;
m_event = 0;
m_adata = 0;
m_bdata = 0;
m_cdata = 0;
m_idata = 0;
#endif
}
return LIBXSTREAM_ERROR_NONE;
}
int multi_dgemm_type::init(const char* name, host_data_type& host_data, int device, int demux, size_t max_batch)
{
LIBXSTREAM_CHECK_CALL(deinit());
const size_t max_msize = max_batch * host_data.max_matrix_size();
m_host_data = &host_data;
m_max_batch = max_batch;
LIBXSTREAM_CHECK_CALL(libxstream_stream_create(&m_stream, device, demux, 0, name));
LIBXSTREAM_CHECK_CALL(libxstream_mem_allocate(device, reinterpret_cast<void**>(&m_adata), sizeof(double) * max_msize, 0));
LIBXSTREAM_CHECK_CALL(libxstream_mem_allocate(device, reinterpret_cast<void**>(&m_bdata), sizeof(double) * max_msize, 0));
LIBXSTREAM_CHECK_CALL(libxstream_mem_allocate(device, reinterpret_cast<void**>(&m_cdata), sizeof(double) * max_msize, 0));
LIBXSTREAM_CHECK_CALL(libxstream_mem_allocate(device, reinterpret_cast<void**>(&m_idata), sizeof(size_t) * max_batch, 0));
LIBXSTREAM_CHECK_CALL(libxstream_fn_create_signature(&m_signature, 6));
LIBXSTREAM_CHECK_CALL(libxstream_fn_input (m_signature, 2, m_idata, libxstream_map_to_type(m_idata), 1, &max_msize));
LIBXSTREAM_CHECK_CALL(libxstream_fn_input (m_signature, 3, m_adata, libxstream_map_to_type(m_adata), 1, &max_msize));
LIBXSTREAM_CHECK_CALL(libxstream_fn_input (m_signature, 4, m_bdata, libxstream_map_to_type(m_bdata), 1, &max_msize));
LIBXSTREAM_CHECK_CALL(libxstream_fn_output(m_signature, 5, m_cdata, libxstream_map_to_type(m_cdata), 1, &max_msize));
return LIBXSTREAM_ERROR_NONE;
}
int multi_dgemm_type::operator()(size_t index, size_t size)
{
LIBXSTREAM_CHECK_CONDITION(ready() && (index + size) <= m_host_data->size());
if (0 < size) {
if (0 == demux()) {
// This manual synchronization prevents multiple threads from queuing work into the *same* stream (at the same time).
// This is only needed if the stream was created without demux support in order to rely on manual synchronization.
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_stream_lock(m_stream));
}
const size_t i0 = m_host_data->idata()[index], i1 = m_host_data->idata()[index+size];
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_memcpy_h2d(m_host_data->adata() + i0, m_adata, sizeof(double) * (i1 - i0), m_stream));
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_memcpy_h2d(m_host_data->bdata() + i0, m_bdata, sizeof(double) * (i1 - i0), m_stream));
// transferring cdata is part of the benchmark; since it is all zeros we could do better with libxstream_memset_zero
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_memcpy_h2d(m_host_data->cdata() + i0, m_cdata, sizeof(double) * (i1 - i0), m_stream));
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_memcpy_h2d(m_host_data->idata() + index, m_idata, sizeof(size_t) * size, m_stream));
#if defined(LIBXSTREAM_DEBUG)
size_t n = 0;
LIBXSTREAM_ASSERT(LIBXSTREAM_ERROR_NONE == libxstream_fn_nargs(m_signature, &n) && 6 == n);
#endif
const size_t nn = i1 - m_host_data->idata()[index+size-1];
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_fn_input(m_signature, 0, &size, libxstream_map_to_type(size), 0, 0));
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_fn_input(m_signature, 1, &nn, libxstream_map_to_type(nn ), 0, 0));
LIBXSTREAM_ASSERT(LIBXSTREAM_ERROR_NONE == libxstream_get_arity(m_signature, &n) && 6 == n);
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_fn_call(m_host_data->process(), m_signature, m_stream, LIBXSTREAM_CALL_DEFAULT));
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_memcpy_d2h(m_cdata, m_host_data->cdata() + i0, sizeof(double) * (i1 - i0), m_stream));
if (0 == demux()) {
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_stream_unlock(m_stream));
}
}
return LIBXSTREAM_ERROR_NONE;
}
libxstream_event* multi_dgemm_type::event()
{
if (0 == m_event) {
libxstream_event_create(&m_event);
LIBXSTREAM_ASSERT(0 != m_event);
}
return m_event;
}
bool multi_dgemm_type::ready() const
{
LIBXSTREAM_ASSERT(0 == m_host_data || (m_signature && m_stream && m_adata && m_bdata && m_cdata && m_idata));
return 0 != m_host_data;
}
int multi_dgemm_type::demux() const
{
LIBXSTREAM_ASSERT(ready());
int value = 0;
LIBXSTREAM_CHECK_CALL_THROW(libxstream_stream_demux(m_stream, &value));
return value;
}
size_t multi_dgemm_type::bytes() const
{
LIBXSTREAM_ASSERT(ready());
return m_max_batch * m_host_data->max_matrix_size() * (3 * sizeof(double) + sizeof(size_t));
}

View file

@ -1,87 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#ifndef MULTI_DGEMM_TYPE_HPP
#define MULTI_DGEMM_TYPE_HPP
#include "../../include/libxstream.h"
class multi_dgemm_type {
public:
class host_data_type {
public:
host_data_type(libxstream_function process, size_t size, const size_t split[]);
~host_data_type();
public:
libxstream_function process() { return m_process; }
const double* adata() const { return m_adata; }
const double* bdata() const { return m_bdata; }
double* cdata() { return m_cdata; }
const size_t* idata() const { return m_idata; }
size_t size() const { return m_size; }
size_t flops() const { return m_flops; }
size_t max_matrix_size() const;
size_t bytes() const;
bool ready() const;
private:
libxstream_function m_process;
double *m_adata, *m_bdata, *m_cdata;
size_t *m_idata, m_size, m_flops;
};
public:
multi_dgemm_type();
~multi_dgemm_type();
private:
int deinit();
public:
int init(const char* name, host_data_type& host_data, int device, int demux, size_t max_batch);
int operator()(size_t index, size_t size);
libxstream_stream* stream() { return m_stream; }
libxstream_event* event();
size_t bytes() const;
bool ready() const;
int demux() const;
private:
host_data_type* m_host_data;
libxstream_argument* m_signature;
libxstream_stream* m_stream;
libxstream_event* m_event;
double *m_adata, *m_bdata, *m_cdata;
size_t *m_idata, m_max_batch;
};
#endif // MULTI_DGEMM_TYPE_HPP

View file

@ -1,205 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#include "multi-dgemm-type.hpp"
#include "../../include/libxstream_begin.h"
#include <stdexcept>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#if defined(_OPENMP)
# include <omp.h>
#endif
#include "../../include/libxstream_end.h"
//#define MULTI_DGEMM_USE_NESTED
#define MULTI_DGEMM_USE_SYNC 1
#define MULTI_DGEMM_USE_CHECK
#define DGEMM dgemm_
LIBXSTREAM_EXTERN_C LIBXSTREAM_TARGET(mic) void DGEMM(
const char*, const char*, const int*, const int*, const int*,
const double*, const double*, const int*, const double*, const int*,
const double*, double*, const int*);
LIBXSTREAM_TARGET(mic) void process(LIBXSTREAM_INVAL(size_t) size, LIBXSTREAM_INVAL(size_t) nn, const size_t* idata,
const double* adata, const double* bdata, double* cdata)
{
if (0 < LIBXSTREAM_GETVAL(size)) {
static const double alpha = 1, beta = 1;
static const char trans = 'N';
const int isize = static_cast<int>(size);
const size_t base = idata[0];
#if defined(_OPENMP) && defined(MULTI_DGEMM_USE_NESTED)
const int nthreads = omp_get_max_threads() / LIBXSTREAM_GETVAL(size);
const int dynamic = omp_get_dynamic(), nested = omp_get_nested();
omp_set_dynamic(0);
omp_set_nested(1);
# pragma omp parallel for schedule(dynamic,1) num_threads(LIBXSTREAM_GETVAL(size))
#endif
for (int i = 0; i < isize; ++i) {
#if defined(_OPENMP) && defined(MULTI_DGEMM_USE_NESTED)
omp_set_num_threads(nthreads);
#endif
LIBXSTREAM_ASSERT(base <= idata[i]);
const size_t i0 = idata[i], i1 = (i + 1) < isize ? idata[i+1] : (i0 + LIBXSTREAM_GETVAL(nn)), n2 = i1 - i0, offset = i0 - base;
const int n = static_cast<int>(std::sqrt(static_cast<double>(n2)) + 0.5);
DGEMM(&trans, &trans, &n, &n, &n, &alpha, adata + offset, &n, bdata + offset, &n, &beta, cdata + offset, &n);
}
#if defined(_OPENMP) && defined(MULTI_DGEMM_USE_NESTED)
omp_set_dynamic(dynamic);
omp_set_nested(nested);
#endif
}
}
int main(int argc, char* argv[])
{
try {
const int nitems = std::max(1 < argc ? std::atoi(argv[1]) : 60, 0);
const int nbatch = std::max(2 < argc ? std::atoi(argv[2]) : 10, 1);
const int nstreams = std::min(std::max(3 < argc ? std::atoi(argv[3]) : 2, 1), LIBXSTREAM_MAX_NSTREAMS);
#if defined(MULTI_DGEMM_USE_SYNC)
const int demux = 4 < argc ? std::atoi(argv[4]) : 1;
#else
const int demux = -1;
#endif
size_t ndevices = 0;
if (LIBXSTREAM_ERROR_NONE != libxstream_get_ndevices(&ndevices) || 0 == ndevices) {
throw std::runtime_error("no device found!");
}
#if !defined(_OPENMP)
fprintf(stderr, "Warning: OpenMP support needed for performance results.\n");
#endif
fprintf(stdout, "Initializing %i device%s and host data...", static_cast<int>(ndevices), 1 == ndevices ? "" : "s");
const size_t split[] = { size_t(nitems * 18.0 / 250.0 + 0.5), size_t(nitems * 74.0 / 250.0 + 0.5) };
multi_dgemm_type::host_data_type host_data(reinterpret_cast<libxstream_function>(&process), nitems, split);
fprintf(stdout, " %.1f MB\n", host_data.bytes() * 1E-6);
fprintf(stdout, "Initializing %i stream%s per device...", nstreams, 1 < nstreams ? "s" : "");
const size_t nstreams_total = ndevices * nstreams;
multi_dgemm_type multi_dgemm[LIBXSTREAM_MAX_NSTREAMS];
for (size_t i = 0; i < nstreams_total; ++i) {
char name[128];
LIBXSTREAM_SNPRINTF(name, sizeof(name), "Stream %i", static_cast<int>(i + 1));
LIBXSTREAM_CHECK_CALL_THROW(multi_dgemm[i].init(name, host_data, static_cast<int>(i % ndevices), demux, static_cast<size_t>(nbatch)));
}
if (0 < nstreams_total) {
fprintf(stdout, " %.1f MB\n", nstreams * multi_dgemm[0].bytes() * 1E-6);
}
const int nbatches = (nitems + nbatch - 1) / nbatch;
fprintf(stdout, "Running %i batch%s of %i item%s...\n", nbatches,
1 < nbatches ? "es" : "", std::min(nbatch, nitems),
1 < nbatch ? "s" : "");
#if defined(_OPENMP)
# if !defined(LIBXSTREAM_OFFLOAD)
omp_set_dynamic(0);
omp_set_nested(0);
# endif
const double start = omp_get_wtime();
# pragma omp parallel for schedule(dynamic)
#endif
for (int i = 0; i < nitems; i += nbatch) {
const size_t j = i / nbatch, n = j % nstreams_total;
multi_dgemm_type& call = multi_dgemm[n];
LIBXSTREAM_CHECK_CALL_ASSERT(call(i, std::min(nbatch, nitems - i)));
#if defined(MULTI_DGEMM_USE_SYNC) && (1 <= MULTI_DGEMM_USE_SYNC)
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_event_record(call.event(), call.stream()));
#endif
// synchronize every Nth iteration with N being the total number of streams
if (n == (nstreams_total - 1)) {
for (size_t k = 0; k < nstreams_total; ++k) {
#if defined(MULTI_DGEMM_USE_SYNC)
# if (2 <= (MULTI_DGEMM_USE_SYNC))
// wait for an event within a stream
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_stream_wait_event(multi_dgemm[0].stream(), multi_dgemm[k].event()));
# elif (1 <= (MULTI_DGEMM_USE_SYNC))
// wait for an event on the host
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_event_synchronize(multi_dgemm[k].event()));
# else
// wait for all work in a stream
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_stream_sync(multi_dgemm[k].stream()));
# endif
#endif
}
}
}
// sync all streams to complete any pending work
LIBXSTREAM_CHECK_CALL_THROW(libxstream_stream_sync(0));
#if defined(_OPENMP)
const double duration = omp_get_wtime() - start;
fprintf(stdout, "Performance: %.1f GFLOPS/s (%s)\n", host_data.flops() * 1E-9 / duration,
0 == demux ? "manual locking" : (0 < demux ? "synchronization" : "automatic locking"));
fprintf(stdout, "Duration: %.1f s\n", duration);
#endif
#if defined(MULTI_DGEMM_USE_CHECK)
std::vector<double> expected(host_data.max_matrix_size());
const size_t testbatchsize = 1;
double max_error = 0;
size_t i0 = 0;
for (int i = 0; i < nitems; ++i) {
const size_t i1 = host_data.idata()[i+1];
const int nn = static_cast<int>(i1 - i0);
std::fill_n(&expected[0], nn, 0.0);
process(LIBXSTREAM_SETVAL(testbatchsize), LIBXSTREAM_SETVAL(nn), host_data.idata() + i, host_data.adata() + i0, host_data.bdata() + i0, &expected[0]);
for (int n = 0; n < nn; ++n) max_error = std::max(max_error, std::abs(expected[n] - host_data.cdata()[i0+n]));
i0 = i1;
}
fprintf(stdout, "Error: %g\n", max_error);
#endif
fprintf(stdout, "Finished\n");
}
catch(const std::exception& e) {
fprintf(stderr, "Error: %s\n", e.what());
return EXIT_FAILURE;
}
catch(...) {
fprintf(stderr, "Error: unknown exception caught!\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

View file

@ -1,9 +0,0 @@
#!/bin/bash
env \
KMP_AFFINITY=scatter \
OFFLOAD_INIT=on_start \
MIC_USE_2MB_BUFFERS=2m \
MIC_ENV_PREFIX=MIC \
MIC_KMP_AFFINITY=balanced,granularity=fine \
./multi-dgemm $*

View file

@ -1,11 +0,0 @@
set terminal png
set output "plot.png"
set grid xtics lc "grey"
set grid ytics lc "grey"
set xlabel "batch size"
set ylabel "GFLOP/s"
set autoscale fix
set mytics 2
plot "plot.txt" using 2:3 notitle smooth sbezier lc "grey", \
"" using 2:3 notitle with points pt 7

View file

@ -1,23 +0,0 @@
#!/bin/bash
FILE="benchmark.txt"
grep -A1 "Running " ${FILE} | tr "\n" " " | sed \
-e "s/Running //g" \
-e "s/ batche*s* of//g" \
-e "s/items*... Performance: //g" \
-e "s/ GFLOPS\/s//g" \
-e "s/ -- /\n/g" \
> plot.txt
if [ "${OS}" != "Windows_NT" ] ; then
gnuplot plot.plt
else
export GDFONTPATH=/cygdrive/c/Windows/Fonts
if [[ -f /cygdrive/c/Program\ Files/gnuplot/bin/wgnuplot ]] ; then
/cygdrive/c/Program\ Files/gnuplot/bin/wgnuplot plot.plt
else
/cygdrive/c/Program\ Files\ \(x86\)/gnuplot/bin/wgnuplot plot.plt
fi
fi

View file

@ -1,4 +0,0 @@
{
"description": "LIBXSMM Sample Code",
"requires": ["../../include"]
}

View file

@ -1,46 +0,0 @@
#!/bin/bash
LIBXSTREAM_ROOT="../.."
NAME=$(basename ${PWD})
ICCOPT="-O2 -xHost -ansi-alias"
ICCLNK=""
GCCOPT="-O2 -march=native"
GCCLNK=""
OPT="-Wall -std=c++0x"
if [[ "" = "${CXX}" ]] ; then
CXX=$(which icpc 2> /dev/null)
if [[ "" != "${CXX}" ]] ; then
OPT+=" ${ICCOPT}"
LNK+=" ${ICCLNK}"
else
CXX="g++"
OPT+=" ${GCCOPT}"
LNK+=" ${GCCLNK}"
fi
else
OPT+=" ${GCCOPT}"
LNK+=" ${GCCLNK}"
fi
if [ "-g" = "$1" ] ; then
OPT+=" -O0 -g"
shift
else
OPT+=" -DNDEBUG"
fi
if [[ "Windows_NT" = "${OS}" ]] ; then
OPT+=" -D_REENTRANT"
LNK+=" -lpthread"
else
OPT+=" -pthread"
fi
${CXX} ${OPT} $* \
-I${LIBXSTREAM_ROOT}/include -I${LIBXSTREAM_ROOT}/src -DLIBXSTREAM_EXPORTED \
${LIBXSTREAM_ROOT}/src/*.cpp *.cpp \
${LNK} -o ${NAME}

View file

@ -1,299 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#include "test.hpp"
#include "../../include/libxstream_begin.h"
#include <stdexcept>
#include <algorithm>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cstdio>
#if defined(_OPENMP)
# include <omp.h>
#endif
#include "../../include/libxstream_end.h"
namespace test_internal {
LIBXSTREAM_TARGET(mic) void check(libxstream_bool& result, LIBXSTREAM_INVAL(char) pattern, const void* buffer, LIBXSTREAM_INVAL(size_t) size)
{
size_t value = 0;
bool ok = true;
// check function is called with using LIBXSTREAM hence introspection may not be available
if (LIBXSTREAM_ERROR_NONE == libxstream_get_argument(buffer, &value)) {
ok = ok && 2 == value;
ok = ok && LIBXSTREAM_ERROR_NONE == libxstream_get_shape(0, value, &value) && LIBXSTREAM_GETVAL(size) == value;
ok = ok && LIBXSTREAM_ERROR_NONE == libxstream_get_arity(0, &value) && 4 == value;
ok = ok && LIBXSTREAM_ERROR_NONE == libxstream_get_dims(0, 0, &value) && 0 == value;
ok = ok && LIBXSTREAM_ERROR_NONE == libxstream_get_dims(0, 1, &value) && 0 == value;
ok = ok && LIBXSTREAM_ERROR_NONE == libxstream_get_dims(0, 2, &value) && 1 == value;
ok = ok && LIBXSTREAM_ERROR_NONE == libxstream_get_dims(0, 3, &value) && 0 == value;
const void* data = 0;
ok = ok && LIBXSTREAM_ERROR_NONE == libxstream_get_data(0, 0, &data) && result == *static_cast<const libxstream_bool*>(data);
ok = ok && LIBXSTREAM_ERROR_NONE == libxstream_get_data(0, 1, &data) && LIBXSTREAM_GETVAL(pattern) == *static_cast<const char*>(data);
ok = ok && LIBXSTREAM_ERROR_NONE == libxstream_get_data(0, 2, &data) && buffer == data;
ok = ok && LIBXSTREAM_ERROR_NONE == libxstream_get_data(0, 3, &data) && LIBXSTREAM_GETVAL(size) == *static_cast<const size_t*>(data);
}
const char *const values = reinterpret_cast<const char*>(buffer);
for (size_t i = 0; i < LIBXSTREAM_GETVAL(size) && ok; ++i) {
ok = LIBXSTREAM_GETVAL(pattern) == values[i];
}
result = ok ? LIBXSTREAM_TRUE : LIBXSTREAM_FALSE;
}
LIBXSTREAM_TARGET(mic) void complex_c(libxstream_bool* ok,
const float* c32, LIBXSTREAM_INVAL(float) freal, LIBXSTREAM_INVAL(float) fimag,
const double* c64, LIBXSTREAM_INVAL(double) dreal, LIBXSTREAM_INVAL(double) dimag)
{
LIBXSTREAM_ASSERT(ok && c32 && c64);
libxstream_bool result = LIBXSTREAM_TRUE;
result = LIBXSTREAM_FALSE != result && LIBXSTREAM_GETVAL(freal) == c32[0];
result = LIBXSTREAM_FALSE != result && LIBXSTREAM_GETVAL(fimag) == c32[1];
result = LIBXSTREAM_FALSE != result && LIBXSTREAM_GETVAL(dreal) == c64[0];
result = LIBXSTREAM_FALSE != result && LIBXSTREAM_GETVAL(dimag) == c64[1];
*ok = result;
}
LIBXSTREAM_TARGET(mic) void complex_cpp(libxstream_bool& ok,
const std::complex<float>& c32, LIBXSTREAM_INVAL(float) freal, LIBXSTREAM_INVAL(float) fimag,
const std::complex<double>& c64, LIBXSTREAM_INVAL(double) dreal, LIBXSTREAM_INVAL(double) dimag)
{
bool result = true;
result = result && LIBXSTREAM_GETVAL(freal) == c32.real();
result = result && LIBXSTREAM_GETVAL(fimag) == c32.imag();
result = result && LIBXSTREAM_GETVAL(dreal) == c64.real();
result = result && LIBXSTREAM_GETVAL(dimag) == c64.imag();
ok = result ? LIBXSTREAM_TRUE : LIBXSTREAM_FALSE;
}
} // namespace test_internal
/* workaround for issue "cannot find address of function"; compile using "make.sh -g" */
const libxstream_function check = reinterpret_cast<libxstream_function>(test_internal::check);
const libxstream_function complex_c = reinterpret_cast<libxstream_function>(test_internal::complex_c);
const libxstream_function complex_cpp = reinterpret_cast<libxstream_function>(test_internal::complex_cpp);
test_type::test_type(int device)
: m_signature(0), m_stream(0), m_event(0)
, m_host_mem(0), m_dev_mem1(0), m_dev_mem2(0)
{
size_t mem_free = 0, mem_avail = 0;
LIBXSTREAM_CHECK_CALL_THROW(libxstream_mem_info(device, &mem_free, &mem_avail));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_stream_create(&m_stream, device, 0, 0, 0));
const size_t size = 4711u * 1024u;
LIBXSTREAM_CHECK_CALL_THROW(libxstream_mem_allocate(-1, &m_host_mem, size, 0));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_mem_allocate(device, &m_dev_mem1, size, 0));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_mem_allocate(device, &m_dev_mem2, size, 0));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_mem_info(device, &mem_free, &mem_avail));
const void* real = 0;
LIBXSTREAM_CHECK_CALL_THROW(libxstream_mem_pointer(-1, m_host_mem, &real));
LIBXSTREAM_CHECK_CONDITION_THROW(m_host_mem == real);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_mem_pointer(device, m_dev_mem1, &real));
#if defined(LIBXSTREAM_OFFLOAD) && (0 != LIBXSTREAM_OFFLOAD)
LIBXSTREAM_CHECK_CONDITION_THROW(m_dev_mem1 != real);
#endif
LIBXSTREAM_CHECK_CALL_THROW(libxstream_mem_pointer(device, m_dev_mem2, &real));
#if defined(LIBXSTREAM_OFFLOAD) && (0 != LIBXSTREAM_OFFLOAD)
LIBXSTREAM_CHECK_CONDITION_THROW(m_dev_mem2 != real);
#endif
const char pattern_a = 'a', pattern_b = 'b';
LIBXSTREAM_ASSERT(pattern_a != pattern_b);
std::fill_n(reinterpret_cast<char*>(m_host_mem), size, pattern_a);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_memcpy_h2d(m_host_mem, m_dev_mem1, size, m_stream));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_memcpy_d2d(m_dev_mem1, m_dev_mem2, size, m_stream));
size_t typesize = 0;
unsigned char *const puc = 0, auc[16], *const* ppuc = &puc, *apuc[16];
LIBXSTREAM_CHECK_CONDITION_THROW(LIBXSTREAM_ERROR_NONE == libxstream_get_typesize(libxstream_map_to_type(puc ), &typesize) && 1 == typesize);
LIBXSTREAM_CHECK_CONDITION_THROW(LIBXSTREAM_ERROR_NONE == libxstream_get_typesize(libxstream_map_to_type(auc ), &typesize) && 1 == typesize);
LIBXSTREAM_CHECK_CONDITION_THROW(LIBXSTREAM_ERROR_NONE == libxstream_get_typesize(libxstream_map_to_type(ppuc), &typesize) && sizeof(void*) == typesize);
LIBXSTREAM_CHECK_CONDITION_THROW(LIBXSTREAM_ERROR_NONE == libxstream_get_typesize(libxstream_map_to_type(apuc), &typesize) && sizeof(void*) == typesize);
size_t nargs = 0, arity = 0;
libxstream_bool ok = LIBXSTREAM_FALSE;
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_create_signature(&m_signature, 4));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_nargs(m_signature, &nargs));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_get_arity(m_signature, &arity));
LIBXSTREAM_CHECK_CONDITION_THROW(4 == nargs && 0 == arity);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_output(m_signature, 0, &ok, libxstream_map_to<libxstream_bool>::type(), 0, 0));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_nargs(m_signature, &nargs));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_get_arity(m_signature, &arity));
LIBXSTREAM_CHECK_CONDITION_THROW(4 == nargs && 1 == arity);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_get_elemsize(m_signature, 0, &typesize));
LIBXSTREAM_CHECK_CONDITION_THROW(sizeof(libxstream_bool) == typesize);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_get_datasize(m_signature, 0, &typesize));
LIBXSTREAM_CHECK_CONDITION_THROW(sizeof(libxstream_bool) == typesize);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_input (m_signature, 1, &pattern_a, libxstream_map_to<char>::type(), 0, 0));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_nargs(m_signature, &nargs));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_get_arity(m_signature, &arity));
LIBXSTREAM_CHECK_CONDITION_THROW(4 == nargs && 2 == arity);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_get_elemsize(m_signature, 1, &typesize));
LIBXSTREAM_CHECK_CONDITION_THROW(1 == typesize);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_get_datasize(m_signature, 1, &typesize));
LIBXSTREAM_CHECK_CONDITION_THROW(1 == typesize);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_input (m_signature, 2, m_dev_mem1, LIBXSTREAM_TYPE_VOID, 1, &size));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_nargs(m_signature, &nargs));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_get_arity(m_signature, &arity));
LIBXSTREAM_CHECK_CONDITION_THROW(4 == nargs && 3 == arity);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_get_elemsize(m_signature, 2, &typesize));
LIBXSTREAM_CHECK_CONDITION_THROW(1 == typesize);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_get_datasize(m_signature, 2, &typesize));
LIBXSTREAM_CHECK_CONDITION_THROW(size == typesize);
// for testing purpose the following argument is weak-typed instead of (..., libxstream_map_to<size_t>::type(), 0, 0)
typesize = sizeof(size_t);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_input (m_signature, 3, &size, LIBXSTREAM_TYPE_VOID, 0, &typesize));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_nargs(m_signature, &nargs));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_get_arity(m_signature, &arity));
LIBXSTREAM_CHECK_CONDITION_THROW(4 == nargs && 4 == arity);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_get_elemsize(m_signature, 3, &typesize));
LIBXSTREAM_CHECK_CONDITION_THROW(sizeof(size_t) == typesize);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_get_datasize(m_signature, 3, &typesize));
LIBXSTREAM_CHECK_CONDITION_THROW(sizeof(size_t) == typesize);
//const libxstream_function check = reinterpret_cast<libxstream_function>(test_internal::check);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_call(check, m_signature, m_stream, LIBXSTREAM_CALL_DEFAULT));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_event_create(&m_event));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_event_record(m_event, m_stream));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_event_synchronize(m_event));
LIBXSTREAM_CHECK_CONDITION_THROW(LIBXSTREAM_FALSE != ok);
libxstream_argument* signature = 0;
const std::complex<float> c32( 1.05f, 19.81f);
const std::complex<double> c64(25.07 , 19.75 );
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_signature(&signature));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_output(signature, 0, &ok, libxstream_map_to_type(ok ), 0, 0));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_input (signature, 1, &c32, libxstream_map_to_type(c32), 0, 0));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_input (signature, 2, reinterpret_cast<const float*>(&c32) + 0, libxstream_map_to_type(c32.real()), 0, 0));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_input (signature, 3, reinterpret_cast<const float*>(&c32) + 1, libxstream_map_to_type(c32.imag()), 0, 0));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_input (signature, 4, &c64, libxstream_map_to_type(c64), 0, 0));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_input (signature, 5, reinterpret_cast<const double*>(&c64) + 0, libxstream_map_to_type(c64.real()), 0, 0));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_input (signature, 6, reinterpret_cast<const double*>(&c64) + 1, libxstream_map_to_type(c64.imag()), 0, 0));
//const libxstream_function complex_c = reinterpret_cast<libxstream_function>(test_internal::complex_c);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_call(complex_c, signature, m_stream, LIBXSTREAM_CALL_DEFAULT));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_stream_sync(m_stream));
LIBXSTREAM_CHECK_CONDITION_THROW(LIBXSTREAM_FALSE != ok);
//const libxstream_function complex_cpp = reinterpret_cast<libxstream_function>(test_internal::complex_cpp);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_fn_call(complex_cpp, signature, m_stream, LIBXSTREAM_CALL_DEFAULT));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_stream_sync(m_stream));
LIBXSTREAM_CHECK_CONDITION_THROW(LIBXSTREAM_FALSE != ok);
std::fill_n(reinterpret_cast<char*>(m_host_mem), size, pattern_b);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_memcpy_d2h(m_dev_mem2, m_host_mem, size, m_stream));
const size_t size2 = size / 2;
LIBXSTREAM_CHECK_CALL_THROW(libxstream_memset_zero(m_dev_mem1, size2, m_stream));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_memset_zero(reinterpret_cast<char*>(m_dev_mem1) + size2, size - size2, m_stream));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_event_record(m_event, m_stream));
int has_occured = 0;
LIBXSTREAM_CHECK_CALL_THROW(libxstream_event_query(m_event, &has_occured));
if (0 == has_occured) {
LIBXSTREAM_CHECK_CALL_THROW(libxstream_event_synchronize(m_event));
}
test_internal::check(ok, LIBXSTREAM_SETVAL(pattern_a), m_host_mem, LIBXSTREAM_SETVAL(size));
LIBXSTREAM_CHECK_CONDITION_THROW(LIBXSTREAM_FALSE != ok);
LIBXSTREAM_CHECK_CALL_THROW(libxstream_memcpy_d2h(m_dev_mem1, m_host_mem, size2, m_stream));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_memcpy_d2h(reinterpret_cast<const char*>(m_dev_mem1) + size2, reinterpret_cast<char*>(m_host_mem) + size2, size - size2, m_stream));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_event_record(m_event, m_stream));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_stream_sync(m_stream));
LIBXSTREAM_CHECK_CALL_THROW(libxstream_event_query(m_event, &has_occured));
LIBXSTREAM_CHECK_CONDITION_THROW(0 != has_occured);
const char zero = 0;
test_internal::check(ok, LIBXSTREAM_SETVAL(zero), m_host_mem, LIBXSTREAM_SETVAL(size));
LIBXSTREAM_CHECK_CONDITION_THROW(LIBXSTREAM_FALSE != ok);
}
test_type::~test_type()
{
int device = -1;
LIBXSTREAM_CHECK_CALL_RETURN(libxstream_stream_device(m_stream, &device));
LIBXSTREAM_CHECK_CALL_RETURN(libxstream_mem_deallocate(-1, m_host_mem));
LIBXSTREAM_CHECK_CALL_RETURN(libxstream_mem_deallocate(device, m_dev_mem1));
LIBXSTREAM_CHECK_CALL_RETURN(libxstream_mem_deallocate(device, m_dev_mem2));
LIBXSTREAM_CHECK_CALL_RETURN(libxstream_fn_destroy_signature(m_signature));
LIBXSTREAM_CHECK_CALL_RETURN(libxstream_stream_destroy(m_stream));
LIBXSTREAM_CHECK_CALL_RETURN(libxstream_event_destroy(m_event));
fprintf(stdout, "TST successfully completed.\n");
}
int main(int argc, char* argv[])
{
try {
#if defined(_OPENMP)
const int ntasks = std::max(1 < argc ? std::atoi(argv[1]) : omp_get_max_threads(), 1);
#else
const int ntasks = std::max(1 < argc ? std::atoi(argv[1]) : 1, 1);
#endif
size_t ndevices = 0;
if (LIBXSTREAM_ERROR_NONE != libxstream_get_ndevices(&ndevices) || 0 == ndevices) {
throw std::runtime_error("no device found!");
}
#if defined(_OPENMP)
// chunksize: limit memory consumption on high core count systems
const int chunksize = std::max(ntasks / LIBXSTREAM_MAX_NDEVICES, 1);
# pragma omp parallel for schedule(dynamic,chunksize)
#endif
for (int i = 0; i < ntasks; ++i) {
const test_type test(i % ndevices);
}
}
catch(const std::exception& e) {
fprintf(stderr, "Error: %s\n", e.what());
return EXIT_FAILURE;
}
catch(...) {
fprintf(stderr, "Error: unknown exception caught!\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

View file

@ -1,51 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#ifndef TEST_HPP
#define TEST_HPP
#include "../../include/libxstream.h"
class test_type {
public:
test_type(int device);
~test_type();
private:
libxstream_argument* m_signature;
libxstream_stream* m_stream;
libxstream_event* m_event;
void* m_host_mem;
void* m_dev_mem1;
void* m_dev_mem2;
};
#endif // TEST_HPP

View file

@ -1,4 +0,0 @@
{
"description": "LIBXSMM Implementation",
"requires": ["../include"]
}

File diff suppressed because it is too large Load diff

View file

@ -1,60 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#ifndef LIBXSTREAM_HPP
#define LIBXSTREAM_HPP
#include <libxstream.h>
#if defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
/** Data type representing a signal. */
typedef uintptr_t libxstream_signal;
typedef void libxstream_lock;
libxstream_lock* libxstream_lock_create();
void libxstream_lock_destroy(libxstream_lock* lock);
void libxstream_lock_acquire(libxstream_lock* lock);
void libxstream_lock_release(libxstream_lock* lock);
bool libxstream_lock_try(libxstream_lock* lock);
size_t nthreads_active();
int this_thread_id();
void this_thread_yield();
void this_thread_sleep(size_t ms = 1);
enum {
LIBXSTREAM_CALL_UNLOCK = (2 * (LIBXSTREAM_CALL_INVALID - 1)),
LIBXSTREAM_CALL_EXTERNAL = (4 * (LIBXSTREAM_CALL_INVALID - 1))
};
#endif // defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
#endif // LIBXSTREAM_HPP

View file

@ -1,377 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#if defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
#include "libxstream_alloc.hpp"
#include <libxstream_begin.h>
#include <algorithm>
#include <libxstream_end.h>
#if defined(__MKL)
# include <mkl.h>
#endif
#if defined(_WIN32)
# include <windows.h>
#else
# include <xmmintrin.h>
# include <sys/mman.h>
#endif
namespace libxstream_alloc_internal {
LIBXSTREAM_TARGET(mic) unsigned int abs(unsigned int a) { return a; }
LIBXSTREAM_TARGET(mic) unsigned long abs(unsigned long a) { return a; }
LIBXSTREAM_TARGET(mic) unsigned long long abs(unsigned long long a) { return a; }
template<typename S, typename T>
LIBXSTREAM_TARGET(mic) S linear_size(size_t dims, const T shape[], S initial_size)
{
LIBXSTREAM_ASSERT(shape);
S result = 0 < dims ? (std::max<S>(initial_size, 1) * static_cast<S>(shape[0])) : initial_size;
#if defined(__INTEL_COMPILER)
# pragma loop_count min(1), max(LIBXSTREAM_MAX_NDIMS), avg(2)
#endif
for (size_t i = 1; i < dims; ++i) result *= static_cast<S>(shape[i]);
return result;
}
} // namespace libxstream_alloc_internal
LIBXSTREAM_TARGET(mic) size_t libxstream_gcd(size_t a, size_t b)
{
while (0 != b) {
const size_t r = a % b;
a = b;
b = r;
}
return a;
}
LIBXSTREAM_TARGET(mic) size_t libxstream_lcm(size_t a, size_t b)
{
using libxstream_alloc_internal::abs;
using std::abs;
return abs(a * b) / libxstream_gcd(a, b);
}
LIBXSTREAM_TARGET(mic) size_t libxstream_alignment(size_t size, size_t alignment)
{
#if defined(LIBXSTREAM_OFFLOAD)
static const size_t max_algn = (LIBXSTREAM_MAX_ALIGN / LIBXSTREAM_MAX_SIMD) * LIBXSTREAM_MAX_SIMD;
static const size_t max_simd = std::min(LIBXSTREAM_MAX_SIMD, LIBXSTREAM_MAX_ALIGN);
#else
static const size_t max_algn = LIBXSTREAM_MAX_SIMD, max_simd = LIBXSTREAM_MAX_SIMD;
#endif
const size_t a = 0 == alignment ? max_algn : ((LIBXSTREAM_MAX_ALIGN / alignment) * alignment);
const size_t b = 0 == alignment ? max_simd : std::min(alignment, static_cast<size_t>(LIBXSTREAM_MAX_ALIGN));
const size_t c = std::max(sizeof(void*), alignment);
return a <= size ? a : (b < size ? b : c);
}
LIBXSTREAM_TARGET(mic) size_t libxstream_align(size_t size, size_t alignment)
{
const size_t auto_alignment = libxstream_alignment(size, alignment);
const size_t aligned = ((size + auto_alignment - 1) / auto_alignment) * auto_alignment;
LIBXSTREAM_ASSERT(aligned == LIBXSTREAM_ALIGN(size, auto_alignment/*pot*/));
return aligned;
}
LIBXSTREAM_TARGET(mic) void* libxstream_align(void* address, size_t alignment)
{
LIBXSTREAM_ASSERT(0 != alignment);
const uintptr_t aligned = ((reinterpret_cast<uintptr_t>(address) + alignment - 1) / alignment) * alignment;
LIBXSTREAM_ASSERT(aligned == LIBXSTREAM_ALIGN(address, alignment/*pot*/));
return reinterpret_cast<void*>(aligned);
}
LIBXSTREAM_TARGET(mic) const void* libxstream_align(const void* address, size_t alignment)
{
LIBXSTREAM_ASSERT(0 != alignment);
const uintptr_t aligned = ((reinterpret_cast<uintptr_t>(address) + alignment - 1) / alignment) * alignment;
LIBXSTREAM_ASSERT(aligned == LIBXSTREAM_ALIGN(address, alignment/*pot*/));
return reinterpret_cast<void*>(aligned);
}
LIBXSTREAM_TARGET(mic) size_t libxstream_linear_size(size_t dims, const size_t shape[], size_t initial_size)
{
return libxstream_alloc_internal::linear_size(dims, shape, initial_size);
}
LIBXSTREAM_TARGET(mic) int libxstream_linear_offset(size_t dims, const int offset[], const size_t shape[])
{
LIBXSTREAM_ASSERT(offset && shape);
int result = 0;
if (0 < dims) {
size_t size = shape[0];
result = offset[0];
#if defined(__INTEL_COMPILER)
# pragma loop_count min(1), max(LIBXSTREAM_MAX_NDIMS), avg(2)
#endif
for (size_t i = 1; i < dims; ++i) {
result += offset[i] * static_cast<int>(size);
size *= shape[i];
}
}
return result;
}
LIBXSTREAM_TARGET(mic) size_t libxstream_linear_address(size_t dims, const int offset[], const size_t shape[], const size_t pitch[])
{
LIBXSTREAM_ASSERT(offset && shape && pitch);
size_t result = 0;
if (0 < dims) {
size_t d = dims - 1;
int p = static_cast<int>(pitch[0]);
result = offset[0] * libxstream_alloc_internal::linear_size<int>(d, shape + 1, 1);
#if defined(__INTEL_COMPILER)
# pragma loop_count min(1), max(LIBXSTREAM_MAX_NDIMS), avg(2)
#endif
for (size_t i = 1; i < dims; ++i) {
result += libxstream_alloc_internal::linear_size(d - i, shape + i + 1, p * offset[i]);
p *= static_cast<int>(pitch[i]);
}
}
return result;
}
int libxstream_real_allocate(void** memory, size_t size, size_t alignment)
{
int result = LIBXSTREAM_ERROR_NONE;
if (memory) {
if (0 < size) {
#if defined(LIBXSTREAM_DEBUG)
LIBXSTREAM_USE_SINK(&alignment);
if (char *const buffer = new char[size]) {
std::fill_n(buffer, size, 0);
*memory = buffer;
}
else {
result = LIBXSTREAM_ERROR_RUNTIME;
}
#elif defined(__MKL)
void *const buffer = mkl_malloc(size, static_cast<int>(libxstream_alignment(size, alignment)));
# if defined(LIBXSTREAM_CHECK)
if (0 != buffer)
# endif
{
*memory = buffer;
}
# if defined(LIBXSTREAM_CHECK)
else {
result = LIBXSTREAM_ERROR_RUNTIME;
}
# endif
#elif defined(_WIN32)
void *const buffer = _aligned_malloc(size, libxstream_alignment(size, alignment));
# if defined(LIBXSTREAM_CHECK)
if (0 != buffer)
# endif
{
*memory = buffer;
}
# if defined(LIBXSTREAM_CHECK)
else {
result = LIBXSTREAM_ERROR_RUNTIME;
}
# endif
#elif defined(__GNUC__)
void *const buffer = _mm_malloc(size, static_cast<int>(libxstream_alignment(size, alignment)));
# if defined(LIBXSTREAM_CHECK)
if (0 != buffer)
# endif
{
*memory = buffer;
}
# if defined(LIBXSTREAM_CHECK)
else {
result = LIBXSTREAM_ERROR_RUNTIME;
}
# endif
#else
# if defined(LIBXSTREAM_CHECK)
result = (0 == posix_memalign(memory, libxstream_alignment(size, alignment), size) && 0 != *memory)
# else
result = (0 == posix_memalign(memory, libxstream_alignment(size, alignment), size))
# endif
? LIBXSTREAM_ERROR_NONE : LIBXSTREAM_ERROR_RUNTIME;
#endif
}
else {
*memory = 0;
}
}
#if defined(LIBXSTREAM_CHECK)
else if (0 != size) {
result = LIBXSTREAM_ERROR_CONDITION;
}
#endif
return result;
}
int libxstream_real_deallocate(const void* memory)
{
if (memory) {
#if defined(LIBXSTREAM_DEBUG)
delete[] static_cast<const char*>(memory);
#elif defined(__MKL)
mkl_free(const_cast<void*>(memory));
#elif defined(_WIN32)
_aligned_free(const_cast<void*>(memory));
#elif defined(__GNUC__)
_mm_free(const_cast<void*>(memory));
#else
free(const_cast<void*>(memory));
#endif
}
return LIBXSTREAM_ERROR_NONE;
}
int libxstream_virt_allocate(void** memory, size_t size, size_t alignment, const void* data, size_t data_size)
{
LIBXSTREAM_CHECK_CONDITION(0 == data_size || 0 != data);
int result = LIBXSTREAM_ERROR_NONE;
if (memory) {
if (0 < size) {
#if !defined(LIBXSTREAM_OFFLOAD) || defined(LIBXSTREAM_DEBUG)
const size_t sanitize = data_size;
char* aligned = 0;
result = libxstream_real_allocate(reinterpret_cast<void**>(&aligned), std::max(size, sanitize), alignment);
LIBXSTREAM_CHECK_ERROR(result);
#elif defined(_WIN32)
const size_t sanitize = data_size + sizeof(void*);
const size_t auto_alignment = libxstream_alignment(std::max(size, sanitize), alignment);
const size_t aligned_size = libxstream_align(std::max(size, sanitize), auto_alignment);
void *const buffer = VirtualAlloc(0, aligned_size, MEM_RESERVE, PAGE_NOACCESS);
LIBXSTREAM_CHECK_CONDITION(0 != buffer);
char *const aligned = static_cast<char*>(VirtualAlloc(libxstream_align(buffer, auto_alignment), sanitize, MEM_COMMIT, PAGE_READWRITE));
LIBXSTREAM_CHECK_CONDITION(buffer <= aligned);
*reinterpret_cast<void**>(aligned) = buffer;
#else
const size_t sanitize = data_size + sizeof(void*) + sizeof(size);
const size_t auto_alignment = libxstream_alignment(std::max(size, sanitize), alignment);
const size_t aligned_size = libxstream_align(std::max(size, sanitize), auto_alignment);
void *const buffer = mmap(0, aligned_size, /*PROT_NONE*/PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS /*| MAP_LOCKED*/, -1, 0);
LIBXSTREAM_CHECK_CONDITION(MAP_FAILED != buffer);
char *const aligned = static_cast<char*>(libxstream_align(buffer, auto_alignment));
LIBXSTREAM_CHECK_CONDITION(buffer <= aligned);
*reinterpret_cast<void**>(aligned) = buffer;
*reinterpret_cast<size_t*>(aligned + sizeof(void*)) = aligned_size;
#endif
if (0 < data_size && 0 != data) {
const char *const src = static_cast<const char*>(data);
char *const dst = static_cast<char*>(libxstream_virt_data(aligned));
for (size_t i = 0; i < data_size; ++i) dst[i] = src[i];
}
*memory = aligned;
}
else {
*memory = 0;
}
}
#if defined(LIBXSTREAM_CHECK)
else if (0 != size) {
result = LIBXSTREAM_ERROR_CONDITION;
}
#endif
return result;
}
int libxstream_virt_deallocate(const void* memory)
{
int result = LIBXSTREAM_ERROR_NONE;
if (memory) {
#if !defined(LIBXSTREAM_OFFLOAD) || defined(LIBXSTREAM_DEBUG)
result = libxstream_real_deallocate(memory);
#elif defined(_WIN32)
void *const unaligned = const_cast<void*>(*static_cast<const void*const*>(memory));
result = FALSE != VirtualFree(unaligned, 0, MEM_RELEASE) ? LIBXSTREAM_ERROR_NONE : LIBXSTREAM_ERROR_RUNTIME;
#else
void *const unaligned = const_cast<void*>(*static_cast<const void*const*>(memory));
const size_t size = *reinterpret_cast<const size_t*>(static_cast<const char*>(memory) + sizeof(void*));
result = 0 == munmap(unaligned, size) ? LIBXSTREAM_ERROR_NONE : LIBXSTREAM_ERROR_RUNTIME;
#endif
}
return result;
}
void* libxstream_virt_data(void* memory)
{
#if !defined(LIBXSTREAM_OFFLOAD) || defined(LIBXSTREAM_DEBUG)
return memory;
#elif defined(_WIN32)
return static_cast<char*>(memory) + sizeof(void*);
#else
return static_cast<char*>(memory) + sizeof(void*) + sizeof(size_t);
#endif
}
const void* libxstream_virt_data(const void* memory)
{
#if !defined(LIBXSTREAM_OFFLOAD) || defined(LIBXSTREAM_DEBUG)
return memory;
#elif defined(_WIN32)
return static_cast<const char*>(memory) + sizeof(void*);
#else
return static_cast<const char*>(memory) + sizeof(void*) + sizeof(size_t);
#endif
}
#endif // defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)

View file

@ -1,64 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#ifndef LIBXSTREAM_ALLOC_HPP
#define LIBXSTREAM_ALLOC_HPP
#include <libxstream_macros.h>
#include <libxstream_begin.h>
#include <cstddef>
#include <libxstream_end.h>
#if defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
LIBXSTREAM_TARGET(mic) size_t libxstream_gcd(size_t a, size_t b);
LIBXSTREAM_TARGET(mic) size_t libxstream_lcm(size_t a, size_t b);
LIBXSTREAM_TARGET(mic) size_t libxstream_alignment(size_t size, size_t alignment);
LIBXSTREAM_TARGET(mic) size_t libxstream_align(size_t size, size_t alignment);
LIBXSTREAM_TARGET(mic) const void* libxstream_align(const void* address, size_t alignment);
LIBXSTREAM_TARGET(mic) void* libxstream_align(void* address, size_t alignment);
LIBXSTREAM_TARGET(mic) size_t libxstream_linear_size(size_t dims, const size_t shape[], size_t initial_size = 1);
LIBXSTREAM_TARGET(mic) int libxstream_linear_offset(size_t dims, const int offset[], const size_t shape[]);
LIBXSTREAM_TARGET(mic) size_t libxstream_linear_address(size_t dims, const int offset[], const size_t shape[], const size_t pitch[]);
int libxstream_real_allocate(void** memory, size_t size, size_t alignment);
int libxstream_real_deallocate(const void* memory);
int libxstream_virt_allocate(void** memory, size_t size, size_t alignment, const void* data = 0, size_t data_size = 0);
int libxstream_virt_deallocate(const void* memory);
void* libxstream_virt_data(void* memory);
const void* libxstream_virt_data(const void* memory);
#endif // defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
#endif // LIBXSTREAM_ALLOC_HPP

View file

@ -1,162 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#if defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
#include "libxstream_argument.hpp"
#include <libxstream_begin.h>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <libxstream_end.h>
int libxstream_construct(libxstream_argument arguments[], size_t arg, libxstream_argument::kind_type kind, const void* value, libxstream_type type, size_t dims, const size_t shape[])
{
size_t typesize = 0;
const bool weak_candidate = LIBXSTREAM_TYPE_VOID == type || (LIBXSTREAM_ERROR_NONE == libxstream_get_typesize(type, &typesize) && 1 == typesize);
LIBXSTREAM_CHECK_CONDITION((((libxstream_argument::kind_invalid == kind || libxstream_argument::kind_inout == kind) && LIBXSTREAM_TYPE_INVALID == type) || LIBXSTREAM_TYPE_INVALID > type)
&& ((0 == dims && 0 == shape) || (0 == dims && 0 != shape && weak_candidate) || (0 < dims))
&& (LIBXSTREAM_MAX_NDIMS) >= dims);
LIBXSTREAM_ASSERT((LIBXSTREAM_MAX_NARGS) >= arg);
libxstream_argument& argument = arguments[arg];
#if defined(LIBXSTREAM_DEBUG)
memset(argument.data.self, 0, sizeof(libxstream_argument)); // avoid false pos. with mem. analysis
#endif
#if defined(LIBXSTREAM_PRINT)
static const char *const context[] = { "", "input", "output", "inout" };
#endif
argument.kind = kind;
argument.dims = dims;
if (shape) {
if (0 < dims || !weak_candidate) {
#if defined(LIBXSTREAM_PRINT)
if (0 == dims && !weak_candidate) {
LIBXSTREAM_PRINT_WARN("libxstream_fn_%s: signature=0x%llx arg=%lu is strong-typed (ignored shape)!",
context[kind], reinterpret_cast<unsigned long long>(arguments), static_cast<unsigned long>(arg));
}
#endif
argument.type = type;
}
else { // 0 == dims && weak_candidate
argument.type = LIBXSTREAM_TYPE_VOID;
LIBXSTREAM_CHECK_CONDITION(sizeof(libxstream_argument::data_union) >= *shape);
argument.shape[0] = shape[0];
}
#if defined(__INTEL_COMPILER)
# pragma loop_count min(0), max(LIBXSTREAM_MAX_NDIMS), avg(2)
#endif
for (size_t i = 0; i < dims; ++i) argument.shape[i] = shape[i];
}
else {
#if defined(LIBXSTREAM_PRINT)
if (0 < dims && 0 == shape) {
LIBXSTREAM_PRINT_WARN("libxstream_fn_%s: signature=0x%llx arg=%lu is weak-typed (no shape information)!",
context[kind], reinterpret_cast<unsigned long long>(arguments), static_cast<unsigned long>(arg));
}
#endif
std::fill_n(argument.shape, dims, 0);
argument.type = type;
}
return libxstream_argument::kind_invalid != kind ? libxstream_set_value(argument, value) : LIBXSTREAM_ERROR_NONE;
}
int libxstream_construct(libxstream_argument* signature, size_t nargs)
{
LIBXSTREAM_CHECK_CONDITION((0 != signature || 0 == nargs) && (LIBXSTREAM_MAX_NARGS) >= nargs);
if (0 != signature) {
#if defined(__INTEL_COMPILER)
# pragma loop_count min(0), max(LIBXSTREAM_MAX_NARGS), avg(LIBXSTREAM_MAX_NARGS/2)
#endif
for (size_t i = 0; i < nargs; ++i) {
LIBXSTREAM_CHECK_CALL(libxstream_construct(signature, i, libxstream_argument::kind_inout, 0, LIBXSTREAM_TYPE_INVALID, 0, 0));
}
LIBXSTREAM_CHECK_CALL(libxstream_construct(signature, nargs, libxstream_argument::kind_invalid, 0, LIBXSTREAM_TYPE_INVALID, 0, 0));
}
return LIBXSTREAM_ERROR_NONE;
}
LIBXSTREAM_TARGET(mic) libxstream_argument::value_union libxstream_get_value(const libxstream_argument& arg, bool byvalue)
{
const void* data = 0;
if (0 != arg.dims || 0 != (libxstream_argument::kind_output & arg.kind) || (byvalue &&
(LIBXSTREAM_TYPE_C32 > arg.type || (LIBXSTREAM_TYPE_VOID == arg.type && sizeof(void*) >= *arg.shape))))
{
char *const dst = reinterpret_cast<char*>(&data);
for (size_t i = 0; i < sizeof(void*); ++i) dst[i] = arg.data.self[i];
}
else { // by-value
data = arg.data.self; // pointer to data
}
libxstream_argument::value_union value;
value.const_pointer = data;
return value;
}
LIBXSTREAM_TARGET(mic) int libxstream_set_value(libxstream_argument& arg, const void* data)
{
if (0 != arg.dims || 0 != (libxstream_argument::kind_output & arg.kind)) { // by-pointer
*reinterpret_cast<const void**>(&arg) = data;
LIBXSTREAM_ASSERT(libxstream_get_value(arg).const_pointer == data);
}
else { // by-value: copy from the given pointer
size_t typesize = 0 != arg.dims ? 1 : *arg.shape;
if (LIBXSTREAM_TYPE_VOID != arg.type) {
LIBXSTREAM_CHECK_CALL(libxstream_get_typesize(arg.type, &typesize));
}
if (data) {
const char *const src = static_cast<const char*>(data);
for (size_t i = 0; i < typesize; ++i) arg.data.self[i] = src[i];
}
else {
for (size_t i = 0; i < typesize; ++i) arg.data.self[i] = 0;
}
// allows to promote smaller types to pointer-size
for (size_t i = typesize; i < sizeof(void*); ++i) arg.data.self[i] = 0;
}
return LIBXSTREAM_ERROR_NONE;
}
#endif // defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)

View file

@ -1,94 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#ifndef LIBXSTREAM_ARGUMENT_HPP
#define LIBXSTREAM_ARGUMENT_HPP
#include <libxstream.h>
#if defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
template<size_t N> struct libxstream_argument_value {};
template<> struct libxstream_argument_value<4> { typedef float type; };
template<> struct libxstream_argument_value<8> { typedef double type; };
extern "C" struct LIBXSTREAM_TARGET(mic) libxstream_argument {
enum kind_type {
kind_invalid = 0,
kind_input = 1,
kind_output = 2,
kind_inout = kind_output | kind_input,
};
// This data member *must* be the first!
union data_union {
char self[sizeof(void*)], c;
uintptr_t pointer;
int8_t i8;
uint8_t u8;
int16_t i16;
uint16_t u16;
int32_t i32;
uint32_t u32;
int64_t i64;
uint64_t u64;
float f32, c32[2];
double f64, c64[2];
} data;
union value_union {
void* pointer;
const void* const_pointer;
typedef libxstream_argument_value<sizeof(void*)>::type value_type;
value_type value;
};
size_t shape[LIBXSTREAM_MAX_NDIMS];
kind_type kind;
libxstream_type type;
size_t dims;
};
int libxstream_construct(libxstream_argument arguments[], size_t arg, libxstream_argument::kind_type kind, const void* value, libxstream_type type, size_t dims, const size_t shape[]);
int libxstream_construct(libxstream_argument* signature, size_t nargs);
LIBXSTREAM_TARGET(mic) libxstream_argument::value_union libxstream_get_value(const libxstream_argument& arg,
#if defined(LIBXSTREAM_CALL_BYVALUE)
bool byvalue = true);
#else
bool byvalue = false);
#endif
LIBXSTREAM_TARGET(mic) int libxstream_set_value(libxstream_argument& arg, const void* data);
#endif // defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
#endif // LIBXSTREAM_ARGUMENT_HPP

View file

@ -1,392 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#if defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
#include "libxstream_capture.hpp"
#include <libxstream_begin.h>
#include <algorithm>
#include <cstdio>
#if defined(LIBXSTREAM_STDFEATURES)
# include <thread>
# include <atomic>
#else
# if defined(__GNUC__)
# include <pthread.h>
# else
# include <Windows.h>
# endif
#endif
#include <libxstream_end.h>
//#define LIBXSTREAM_CAPTURE_DEBUG
//#define LIBXSTREAM_CAPTURE_UNLOCK_LATE
namespace libxstream_capture_internal {
class queue_type {
public:
queue_type()
: m_lock(libxstream_lock_create())
, m_index(0)
#if defined(LIBXSTREAM_STDFEATURES)
, m_thread() // do not start here
#else
, m_thread(0)
#endif
, m_size(0)
, m_status(LIBXSTREAM_ERROR_NONE)
{
std::fill_n(m_buffer, LIBXSTREAM_MAX_QSIZE, static_cast<libxstream_capture_base*>(0));
#if defined(LIBXSTREAM_STDFEATURES)
std::thread(run, this).swap(m_thread);
#else
# if defined(__GNUC__)
pthread_create(&m_thread, 0, run, this);
# else
m_thread = CreateThread(0, 0, run, this, 0, 0);
# endif
#endif
}
~queue_type() {
// terminates the background thread
push(terminator, true);
#if defined(LIBXSTREAM_STDFEATURES)
m_thread.detach();
#else
# if defined(__GNUC__)
pthread_detach(m_thread);
# else
CloseHandle(m_thread);
# endif
#endif
#if defined(LIBXSTREAM_DEBUG)
size_t dangling = 0;
for (size_t i = 0; i < LIBXSTREAM_MAX_QSIZE; ++i) {
const libxstream_capture_base* item = m_buffer[i];
if (0 != item && terminator != item) {
m_buffer[i] = 0;
++dangling;
delete item;
}
}
if (0 < dangling) {
LIBXSTREAM_PRINT_WARN("%lu work item%s dangling!", static_cast<unsigned long>(dangling), 1 < dangling ? "s are" : " is");
}
#endif
libxstream_lock_destroy(m_lock);
}
public:
int status(int code) {
#if defined(LIBXSTREAM_STDFEATURES)
return std::atomic_exchange(&m_status, code);
#elif defined(_OPENMP)
int result = 0;
# pragma omp critical
{
result = m_status;
m_status = code;
}
return result;
#else // generic
int result = 0;
libxstream_lock_acquire(m_lock);
result = m_status;
m_status = code;
libxstream_lock_release(m_lock);
return result;
#endif
}
bool empty() const {
return 0 == get();
}
/*size_t size() const {
const size_t offset = m_size, index = m_index;
const libxstream_capture_base *const entry = m_buffer[offset%LIBXSTREAM_MAX_QSIZE];
return 0 != entry ? (offset - index) : (std::max<size_t>(offset - index, 1) - 1);
}*/
void push(const libxstream_capture_base& capture_region, bool wait) {
push(&capture_region, wait);
}
libxstream_capture_base* get() const { // not thread-safe!
return m_buffer[m_index%LIBXSTREAM_MAX_QSIZE];
}
void pop() { // not thread-safe!
LIBXSTREAM_ASSERT(!empty());
m_buffer[m_index%LIBXSTREAM_MAX_QSIZE] = 0;
++m_index;
}
private:
void push(const libxstream_capture_base* capture_region, bool wait) {
LIBXSTREAM_ASSERT(0 != capture_region);
libxstream_capture_base** entry = 0;
#if defined(LIBXSTREAM_STDFEATURES)
entry = m_buffer + (m_size++ % LIBXSTREAM_MAX_QSIZE);
#elif defined(_OPENMP)
size_t size1 = 0;
# if (201107 <= _OPENMP)
# pragma omp atomic capture
# else
# pragma omp critical
# endif
size1 = ++m_size;
entry = m_buffer + ((size1 - 1) % LIBXSTREAM_MAX_QSIZE);
#else // generic
libxstream_lock_acquire(m_lock);
entry = m_buffer + (m_size++ % LIBXSTREAM_MAX_QSIZE);
libxstream_lock_release(m_lock);
#endif
LIBXSTREAM_ASSERT(0 != entry);
#if defined(LIBXSTREAM_DEBUG)
if (0 != *entry) {
LIBXSTREAM_PRINT_WARN0("queuing work is stalled!");
}
#endif
// stall the push if LIBXSTREAM_MAX_QSIZE is exceeded
while (0 != *entry) {
this_thread_yield();
}
LIBXSTREAM_ASSERT(0 == *entry);
libxstream_capture_base* new_entry = terminator != capture_region ? capture_region->clone() : terminator;
*entry = new_entry;
if (wait) {
while (new_entry == *entry) {
this_thread_yield();
}
}
}
#if defined(LIBXSTREAM_STDFEATURES) || defined(__GNUC__)
static void* run(void* queue)
#else
static DWORD WINAPI run(_In_ LPVOID queue)
#endif
{
queue_type& q = *static_cast<queue_type*>(queue);
libxstream_capture_base* capture_region = 0;
bool never = false;
#if defined(LIBXSTREAM_ASYNCHOST) && defined(_OPENMP) && !defined(LIBXSTREAM_OFFLOAD)
# pragma omp parallel
# pragma omp master
#endif
for (;;) {
size_t cycle = 0;
while (0 == (capture_region = q.get())) {
if ((LIBXSTREAM_WAIT_ACTIVE_CYCLES) > cycle) {
this_thread_yield();
++cycle;
}
else {
this_thread_sleep();
}
}
if (terminator != capture_region) {
(*capture_region)();
delete capture_region;
q.pop();
}
else {
q.pop();
if (never) break;
}
}
#if defined(LIBXSTREAM_STDFEATURES) || defined(__GNUC__)
return queue;
#else
return EXIT_SUCCESS;
#endif
}
private:
static libxstream_capture_base *const terminator;
libxstream_capture_base* m_buffer[LIBXSTREAM_MAX_QSIZE];
libxstream_lock* m_lock;
size_t m_index;
#if defined(LIBXSTREAM_STDFEATURES)
std::thread m_thread;
std::atomic<size_t> m_size;
std::atomic<int> m_status;
#elif defined(__GNUC__)
pthread_t m_thread;
size_t m_size;
int m_status;
#else
HANDLE m_thread;
size_t m_size;
int m_status;
#endif
#if defined(LIBXSTREAM_CAPTURE_DEBUG)
};
#else
} queue;
#endif
/*static*/ libxstream_capture_base *const queue_type::terminator = reinterpret_cast<libxstream_capture_base*>(-1);
} // namespace libxstream_capture_internal
libxstream_capture_base::libxstream_capture_base(size_t argc, const arg_type argv[], libxstream_stream* stream, int flags)
: m_function(0)
, m_stream(stream)
, m_flags(flags)
#if defined(LIBXSTREAM_THREADLOCAL_SIGNALS) && defined(LIBXSTREAM_ASYNC) && (0 != (2*LIBXSTREAM_ASYNC+1)/2)
, m_thread(this_thread_id())
#endif
#if defined(LIBXSTREAM_CAPTURE_UNLOCK_LATE)
, m_unlock(false)
#else
, m_unlock(true)
#endif
{
if (2 == argc && (argv[0].signature() || argv[1].signature())) {
const libxstream_argument* signature = 0;
if (argv[1].signature()) {
m_function = *reinterpret_cast<const libxstream_function*>(argv + 0);
signature = static_cast<const libxstream_argument*>(libxstream_get_value(argv[1]).const_pointer);
}
else {
LIBXSTREAM_ASSERT(argv[0].signature());
m_function = *reinterpret_cast<const libxstream_function*>(argv + 1);
signature = static_cast<const libxstream_argument*>(libxstream_get_value(argv[0]).const_pointer);
}
size_t arity = 0;
if (signature) {
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_get_arity(signature, &arity));
#if defined(__INTEL_COMPILER)
# pragma loop_count min(0), max(LIBXSTREAM_MAX_NARGS), avg(LIBXSTREAM_MAX_NARGS/2)
#endif
for (size_t i = 0; i < arity; ++i) m_signature[i] = signature[i];
}
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_construct(m_signature, arity, libxstream_argument::kind_invalid, 0, LIBXSTREAM_TYPE_INVALID, 0, 0));
}
else {
LIBXSTREAM_ASSERT(argc <= (LIBXSTREAM_MAX_NARGS));
for (size_t i = 0; i < argc; ++i) m_signature[i] = argv[i];
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_construct(m_signature, argc, libxstream_argument::kind_invalid, 0, LIBXSTREAM_TYPE_INVALID, 0, 0));
#if defined(LIBXSTREAM_DEBUG)
size_t arity = 0;
LIBXSTREAM_ASSERT(LIBXSTREAM_ERROR_NONE == libxstream_get_arity(m_signature, &arity) && arity == argc);
#endif
}
if (stream) {
if (0 == (flags & LIBXSTREAM_CALL_WAIT) && 0 != stream->demux()) {
stream->lock(0 > stream->demux());
}
stream->begin();
}
}
libxstream_capture_base::~libxstream_capture_base()
{
if (m_unlock && m_stream) {
m_stream->end();
if (0 != (m_flags & LIBXSTREAM_CALL_UNLOCK) && 0 != m_stream->demux()) {
m_stream->unlock();
}
}
}
int libxstream_capture_base::status(int code)
{
#if !defined(LIBXSTREAM_CAPTURE_DEBUG)
return libxstream_capture_internal::queue.status(code);
#else
return code;
#endif
}
int libxstream_capture_base::thread() const
{
#if defined(LIBXSTREAM_THREADLOCAL_SIGNALS) && defined(LIBXSTREAM_ASYNC) && (0 != (2*LIBXSTREAM_ASYNC+1)/2)
return m_thread;
#else
return 0;
#endif
}
libxstream_capture_base* libxstream_capture_base::clone() const
{
libxstream_capture_base *const instance = virtual_clone();
#if defined(LIBXSTREAM_CAPTURE_UNLOCK_LATE)
instance->m_unlock = true;
#else
instance->m_unlock = false;
#endif
return instance;
}
void libxstream_capture_base::operator()()
{
virtual_run();
}
int libxstream_enqueue(const libxstream_capture_base& capture_region, bool wait)
{
#if !defined(LIBXSTREAM_CAPTURE_DEBUG)
# if defined(LIBXSTREAM_SYNCHRONOUS)
libxstream_use_sink(&wait);
libxstream_capture_internal::queue.push(capture_region, true);
# else
libxstream_capture_internal::queue.push(capture_region, wait);
# endif
return libxstream_capture_internal::queue.status(LIBXSTREAM_ERROR_NONE);
#else
libxstream_use_sink(&wait);
libxstream_capture_base *const capture_region_clone = capture_region.clone();
(*capture_region_clone)();
delete capture_region_clone;
return LIBXSTREAM_ERROR_NONE;
#endif
}
#endif // defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)

View file

@ -1,201 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#ifndef LIBXSTREAM_CAPTURE_HPP
#define LIBXSTREAM_CAPTURE_HPP
#include "libxstream_argument.hpp"
#include "libxstream_stream.hpp"
#if defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
#define LIBXSTREAM_OFFLOAD_ALLOC alloc_if(1) free_if(0)
#define LIBXSTREAM_OFFLOAD_FREE alloc_if(0) free_if(1)
#define LIBXSTREAM_OFFLOAD_REUSE alloc_if(0) free_if(0)
#define LIBXSTREAM_OFFLOAD_REFRESH length(0) LIBXSTREAM_OFFLOAD_REUSE
#define LIBXSTREAM_OFFLOAD_DATA(ARG, IS_SCALAR) inout(ARG: length(((IS_SCALAR)*sizeof(libxstream_argument::data_union))) alloc_if(IS_SCALAR) free_if(IS_SCALAR))
#define LIBXSTREAM_ASYNC_PENDING (capture_region_pending)
#define LIBXSTREAM_ASYNC_READY (0 == (LIBXSTREAM_ASYNC_PENDING))
#define LIBXSTREAM_ASYNC_STREAM (m_stream)
#define LIBXSTREAM_ASYNC_DEVICE (capture_region_device)
#define LIBXSTREAM_ASYNC_DEVICE_UPDATE(DEVICE) LIBXSTREAM_ASYNC_DEVICE = (DEVICE)
#if defined(LIBXSTREAM_OFFLOAD) && (0 != LIBXSTREAM_OFFLOAD) && defined(LIBXSTREAM_ASYNC) && (0 != (2*LIBXSTREAM_ASYNC+1)/2)
# if (1 == (2*LIBXSTREAM_ASYNC+1)/2) // asynchronous offload
# define LIBXSTREAM_ASYNC_DECL \
libxstream_signal capture_region_signal_consumed = capture_region_signal
# define LIBXSTREAM_ASYNC_TARGET target(mic:LIBXSTREAM_ASYNC_DEVICE)
# define LIBXSTREAM_ASYNC_TARGET_SIGNAL LIBXSTREAM_ASYNC_TARGET signal(capture_region_signal_consumed++)
# define LIBXSTREAM_ASYNC_TARGET_WAIT LIBXSTREAM_ASYNC_TARGET_SIGNAL wait(LIBXSTREAM_ASYNC_PENDING)
# elif (2 == (2*LIBXSTREAM_ASYNC+1)/2) // compiler streams
# define LIBXSTREAM_ASYNC_DECL \
const _Offload_stream handle_ = LIBXSTREAM_ASYNC_STREAM ? LIBXSTREAM_ASYNC_STREAM->handle() : 0; \
libxstream_signal capture_region_signal_consumed = capture_region_signal
# define LIBXSTREAM_ASYNC_TARGET target(mic) stream(handle_)
# define LIBXSTREAM_ASYNC_TARGET_SIGNAL LIBXSTREAM_ASYNC_TARGET signal(capture_region_signal_consumed++)
# define LIBXSTREAM_ASYNC_TARGET_WAIT LIBXSTREAM_ASYNC_TARGET_SIGNAL
# endif
#elif defined(LIBXSTREAM_OFFLOAD) && (0 != LIBXSTREAM_OFFLOAD) // synchronous offload
# if defined(LIBXSTREAM_DEBUG)
# define LIBXSTREAM_ASYNC_DECL const libxstream_signal capture_region_signal_consumed = capture_region_signal + 1
# else
# define LIBXSTREAM_ASYNC_DECL const libxstream_signal capture_region_signal_consumed = capture_region_signal;
# endif
# define LIBXSTREAM_ASYNC_TARGET target(mic:LIBXSTREAM_ASYNC_DEVICE)
# define LIBXSTREAM_ASYNC_TARGET_SIGNAL LIBXSTREAM_ASYNC_TARGET
# define LIBXSTREAM_ASYNC_TARGET_WAIT LIBXSTREAM_ASYNC_TARGET_SIGNAL
#else
# if defined(LIBXSTREAM_DEBUG)
# define LIBXSTREAM_ASYNC_DECL libxstream_signal capture_region_signal_consumed = capture_region_signal + 1
# else
# define LIBXSTREAM_ASYNC_DECL libxstream_signal capture_region_signal_consumed = capture_region_signal;
# endif
# define LIBXSTREAM_ASYNC_TARGET
# define LIBXSTREAM_ASYNC_TARGET_SIGNAL
# define LIBXSTREAM_ASYNC_TARGET_WAIT
#endif
#define LIBXSTREAM_ASYNC_BEGIN(STREAM, ...) do { \
libxstream_stream *const libxstream_capture_stream = cast_to_stream(STREAM); \
const libxstream_capture_base::arg_type libxstream_capture_argv[] = { __VA_ARGS__ }; \
struct libxstream_capture: public libxstream_capture_base { \
libxstream_capture(size_t argc, const arg_type argv[], libxstream_stream* stream, int flags, int& result) \
: libxstream_capture_base(argc, argv, stream, flags) \
{ \
result = libxstream_enqueue(*this, 0 != (flags & LIBXSTREAM_CALL_WAIT)); \
} \
libxstream_capture* virtual_clone() const { \
return new libxstream_capture(*this); \
} \
void virtual_run() { \
const libxstream_signal LIBXSTREAM_ASYNC_PENDING = LIBXSTREAM_ASYNC_STREAM ? LIBXSTREAM_ASYNC_STREAM->pending(thread()) : 0; \
int LIBXSTREAM_ASYNC_DEVICE = LIBXSTREAM_ASYNC_STREAM ? LIBXSTREAM_ASYNC_STREAM->device() : val<int,0>(); \
const libxstream_signal capture_region_signal = LIBXSTREAM_ASYNC_STREAM ? LIBXSTREAM_ASYNC_STREAM->signal() : 0; \
LIBXSTREAM_ASYNC_DECL; libxstream_use_sink(&LIBXSTREAM_ASYNC_DEVICE); libxstream_use_sink(&LIBXSTREAM_ASYNC_PENDING); do
#define LIBXSTREAM_ASYNC_END(FLAGS, RESULT) while(libxstream_not_constant(LIBXSTREAM_FALSE)); \
if (LIBXSTREAM_ASYNC_STREAM && capture_region_signal != capture_region_signal_consumed) { \
LIBXSTREAM_ASYNC_STREAM->pending(thread(), capture_region_signal); \
} \
} \
} capture_region(sizeof(libxstream_capture_argv) / sizeof(*libxstream_capture_argv), \
libxstream_capture_argv, libxstream_capture_stream, FLAGS, RESULT); \
} while(libxstream_not_constant(LIBXSTREAM_FALSE))
struct libxstream_capture_base {
public:
class arg_type: public libxstream_argument {
public:
arg_type(): m_signature(false) {
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_construct(this, 0, kind_inout, 0, LIBXSTREAM_TYPE_INVALID, 0, 0));
}
arg_type(libxstream_function function): m_signature(false) {
const size_t size = sizeof(void*);
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_construct(this, 0, kind_input, &function, LIBXSTREAM_TYPE_VOID, 0, &size));
}
arg_type(const libxstream_argument* signature): m_signature(true) {
const size_t size = sizeof(libxstream_argument*);
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_construct(this, 0, kind_input, signature, LIBXSTREAM_TYPE_VOID, 1, &size));
}
template<typename T> arg_type(T arg): m_signature(false) {
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_construct(this, 0, kind_input, &arg, libxstream_map_to<T>::type(), 0, 0));
}
template<typename T> arg_type(T* arg): m_signature(false) {
const size_t unknown = 0;
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_construct(this, 0, kind_inout, reinterpret_cast<void*>(arg), libxstream_map_to<T>::type(), 1, &unknown));
}
template<typename T> arg_type(const T* arg): m_signature(false) {
const size_t unknown = 0;
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_construct(this, 0, kind_input, reinterpret_cast<const void*>(arg), libxstream_map_to<T>::type(), 1, &unknown));
}
public:
bool signature() const { return m_signature; }
private:
bool m_signature;
};
public:
libxstream_capture_base(size_t argc, const arg_type argv[], libxstream_stream* stream, int flags);
virtual ~libxstream_capture_base();
public:
template<typename T,size_t i> T& val() {
#if defined(LIBXSTREAM_DEBUG)
size_t arity = 0;
LIBXSTREAM_ASSERT(LIBXSTREAM_ERROR_NONE == libxstream_get_arity(m_signature, &arity) && i < arity);
#endif
return *reinterpret_cast<T*>(&m_signature[i]);
}
template<typename T,size_t i> T val() const {
#if defined(LIBXSTREAM_DEBUG)
size_t arity = 0;
LIBXSTREAM_ASSERT(LIBXSTREAM_ERROR_NONE == libxstream_get_arity(m_signature, &arity) && i < arity);
#endif
return *reinterpret_cast<const T*>(&m_signature[i]);
}
template<typename T,size_t i> T* ptr() {
#if defined(LIBXSTREAM_DEBUG)
size_t arity = 0;
LIBXSTREAM_ASSERT(LIBXSTREAM_ERROR_NONE == libxstream_get_arity(m_signature, &arity) && i < arity);
#endif
return *reinterpret_cast<T**>(&m_signature[i]);
}
int status(int code);
int thread() const;
libxstream_capture_base* clone() const;
void operator()();
private:
virtual libxstream_capture_base* virtual_clone() const = 0;
virtual void virtual_run() = 0;
protected:
libxstream_argument m_signature[(LIBXSTREAM_MAX_NARGS)+1];
libxstream_function m_function;
libxstream_stream* m_stream;
int m_flags;
private:
#if defined(LIBXSTREAM_THREADLOCAL_SIGNALS) && defined(LIBXSTREAM_ASYNC) && (0 != (2*LIBXSTREAM_ASYNC+1)/2)
int m_thread;
#endif
bool m_unlock;
};
int libxstream_enqueue(const libxstream_capture_base& capture_region, bool wait);
#endif // defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
#endif // LIBXSTREAM_CAPTURE_HPP

View file

@ -1,74 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#if defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
#include "libxstream_context.hpp"
#include "libxstream.hpp"
libxstream_context& libxstream_context::instance()
{
LIBXSTREAM_TARGET(mic) static LIBXSTREAM_TLS libxstream_context* pcontext = 0;
if (0 == pcontext) {
LIBXSTREAM_TARGET(mic) static LIBXSTREAM_TLS libxstream_context context;
context.flags = LIBXSTREAM_CALL_EXTERNAL;
context.signature = 0;
pcontext = &context;
}
return *pcontext;
}
libxstream_context& libxstream_context::instance(const libxstream_argument signature_[], int flags_)
{
libxstream_context& context = instance();
LIBXSTREAM_ASSERT(LIBXSTREAM_CALL_EXTERNAL != flags_);
context.signature = signature_;
context.flags = flags_;
return context;
}
LIBXSTREAM_TARGET(mic) const libxstream_argument* libxstream_find(const libxstream_context& context, const void* variable)
{
const libxstream_argument* argument = 0;
if (context.signature) {
for (const libxstream_argument* argi = context.signature; LIBXSTREAM_TYPE_INVALID != argi->type; ++argi) {
LIBXSTREAM_ASSERT(libxstream_argument::kind_invalid != argi->kind);
if (variable == libxstream_get_value(*argi, false).const_pointer) {
argument = argi;
break;
}
}
}
return argument;
}
#endif // defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)

View file

@ -1,50 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#ifndef LIBXSTREAM_CONTEXT_HPP
#define LIBXSTREAM_CONTEXT_HPP
#include "libxstream_argument.hpp"
#if defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
struct LIBXSTREAM_TARGET(mic) libxstream_context {
static libxstream_context& instance();
static libxstream_context& instance(const libxstream_argument signature[], int flags);
const libxstream_argument* signature;
int flags;
};
LIBXSTREAM_TARGET(mic) const libxstream_argument* libxstream_find(const libxstream_context& context, const void* variable);
#endif // defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
#endif // LIBXSTREAM_CONTEXT_HPP

View file

@ -1,218 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#if defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
#include "libxstream_event.hpp"
#include "libxstream_capture.hpp"
#include <libxstream_begin.h>
#include <algorithm>
#include <libxstream_end.h>
#if defined(LIBXSTREAM_OFFLOAD) && (0 != LIBXSTREAM_OFFLOAD)
# include <offload.h>
#endif
// allows to wait for an event issued prior to the pending signal
//#define LIBXSTREAM_EVENT_WAIT_PAST
libxstream_event::libxstream_event()
: m_expected(0)
{}
size_t libxstream_event::expected() const
{
LIBXSTREAM_ASSERT((LIBXSTREAM_MAX_NDEVICES * LIBXSTREAM_MAX_NSTREAMS) >= m_expected);
return m_expected;
}
int libxstream_event::reset()
{
int result = LIBXSTREAM_ERROR_NONE;
LIBXSTREAM_ASYNC_BEGIN(0, -2/*invalid device*/, m_slots, &m_expected)
{
#if defined(LIBXSTREAM_DEBUG)
std::fill_n(ptr<slot_type,1>(), LIBXSTREAM_MAX_NDEVICES * LIBXSTREAM_MAX_NSTREAMS, slot_type());
#endif
*ptr<size_t,2>() = 0;
}
LIBXSTREAM_ASYNC_END(LIBXSTREAM_CALL_DEFAULT | LIBXSTREAM_CALL_UNLOCK, result);
return result;
}
int libxstream_event::enqueue(libxstream_stream& stream, bool reset)
{
int result = LIBXSTREAM_ERROR_NONE;
LIBXSTREAM_ASYNC_BEGIN(stream, m_slots, &m_expected, reset)
{
slot_type *const slots = ptr<slot_type,0>();
size_t& expected = *ptr<size_t,1>();
const bool reset = val<bool,2>();
if (reset) {
#if defined(LIBXSTREAM_DEBUG)
std::fill_n(slots, LIBXSTREAM_MAX_NDEVICES * LIBXSTREAM_MAX_NSTREAMS, slot_type());
#endif
expected = 0;
}
#if defined(LIBXSTREAM_DEBUG)
LIBXSTREAM_ASSERT((LIBXSTREAM_MAX_NDEVICES * LIBXSTREAM_MAX_NSTREAMS) > expected);
#endif
slot_type& slot = slots[expected];
slot = slot_type(thread(), *LIBXSTREAM_ASYNC_STREAM);
++expected;
}
LIBXSTREAM_ASYNC_END(LIBXSTREAM_CALL_DEFAULT | LIBXSTREAM_CALL_UNLOCK, result);
return result;
}
int libxstream_event::query(bool& occurred, const libxstream_stream* exclude) const
{
int result = LIBXSTREAM_ERROR_NONE;
LIBXSTREAM_ASYNC_BEGIN(0, -2/*invalid device*/, &occurred, exclude, m_slots, &m_expected)
{
const libxstream_stream *const exclude = ptr<const libxstream_stream,2>();
slot_type *const slots = ptr<slot_type,3>();
const size_t expected = *ptr<const size_t,4>();
bool occurred = true; // everythig "occurred" if nothing is expected
for (size_t i = 0; i < expected; ++i) {
slot_type& slot = slots[i];
const libxstream_signal pending_slot = slot.pending();
libxstream_stream *const stream = slot.stream();
if (exclude != stream && 0 != pending_slot) {
const libxstream_signal pending_stream = stream ? stream->pending(thread()) : 0;
if (0 != pending_stream) {
#if defined(LIBXSTREAM_EVENT_WAIT_PAST)
const libxstream_signal signal = pending_slot;
#else
const libxstream_signal signal = pending_stream;
#endif
#if defined(LIBXSTREAM_OFFLOAD) && (0 != LIBXSTREAM_OFFLOAD) && !defined(__MIC__) && defined(LIBXSTREAM_ASYNC) && (0 != (2*LIBXSTREAM_ASYNC+1)/2)
if (0 != _Offload_signaled(stream->device(), reinterpret_cast<void*>(signal)))
#endif
{
if (signal == pending_stream) {
stream->pending(thread(), 0);
}
slot.pending(0);
}
}
else {
slot.pending(0);
}
occurred = occurred && 0 == slot.pending();
}
}
*ptr<bool,1>() = occurred;
}
LIBXSTREAM_ASYNC_END(LIBXSTREAM_CALL_DEFAULT | LIBXSTREAM_CALL_WAIT, result);
return result;
}
int libxstream_event::wait(const libxstream_stream* exclude)
{
int result = LIBXSTREAM_ERROR_NONE;
LIBXSTREAM_ASYNC_BEGIN(0, -2/*invalid device*/, exclude, m_slots, &m_expected)
{
const libxstream_stream *const exclude = ptr<const libxstream_stream,1>();
slot_type *const slots = ptr<slot_type,2>();
const size_t expected = *ptr<const size_t,3>();
size_t completed = 0;
for (size_t i = 0; i < expected; ++i) {
slot_type& slot = slots[i];
libxstream_stream *const stream = slot.stream();
const libxstream_signal pending_slot = slot.pending();
if (exclude != stream && 0 != pending_slot) {
const libxstream_signal pending_stream = stream ? stream->pending(thread()) : 0;
if (0 != pending_stream) {
#if defined(LIBXSTREAM_EVENT_WAIT_PAST)
const libxstream_signal signal = pending_slot;
#else
const libxstream_signal signal = pending_stream;
#endif
#if defined(LIBXSTREAM_OFFLOAD) && defined(LIBXSTREAM_ASYNC) && (0 != (2*LIBXSTREAM_ASYNC+1)/2)
if (0 <= stream->device()) {
LIBXSTREAM_ASYNC_DEVICE_UPDATE(stream->device());
# pragma offload_wait LIBXSTREAM_ASYNC_TARGET wait(signal)
}
#endif
if (signal == pending_stream) {
stream->pending(thread(), 0);
}
slot.pending(0);
}
else {
slot.pending(0);
}
completed += 0 == slot.pending() ? 1 : 0;
}
}
LIBXSTREAM_ASSERT(completed <= expected);
// reset only if all slots fired (need to iterate all slots otherwise)
if (completed == *ptr<const size_t,3>()) {
*ptr<size_t,3>() = 0;
}
}
LIBXSTREAM_ASYNC_END(LIBXSTREAM_CALL_DEFAULT | LIBXSTREAM_CALL_WAIT | LIBXSTREAM_CALL_UNLOCK, result);
return result;
}
libxstream_event::slot_type::slot_type(int thread, libxstream_stream& stream)
: m_stream(&stream) // no need to lock the stream
, m_pending(stream.pending(thread))
{}
#endif // defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)

View file

@ -1,75 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#ifndef LIBXSTREAM_EVENT_HPP
#define LIBXSTREAM_EVENT_HPP
#include "libxstream.hpp"
#if defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
struct libxstream_event {
public:
libxstream_event();
public:
// Number of streams the event was recorded for.
size_t expected() const;
// Reset the event.
int reset();
// Enqueue this event into the given stream; reset to start over.
int enqueue(libxstream_stream& stream, bool reset);
// Query whether the event already happened or not.
int query(bool& occurred, const libxstream_stream* exclude = 0) const;
// Wait for the event to happen.
int wait(const libxstream_stream* exclude = 0);
private:
class slot_type {
libxstream_stream* m_stream;
mutable libxstream_signal m_pending;
public:
slot_type(): m_stream(0), m_pending(0) {}
slot_type(int thread, libxstream_stream& stream);
const libxstream_stream* stream() const { return m_stream; }
libxstream_stream* stream() { return m_stream; }
libxstream_signal pending() const { return m_pending; }
void pending(libxstream_signal signal) { m_pending = signal; }
} m_slots[LIBXSTREAM_MAX_NDEVICES*LIBXSTREAM_MAX_NSTREAMS];
size_t m_expected;
};
#endif // defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
#endif // LIBXSTREAM_EVENT_HPP

View file

@ -1,527 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#if defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
#include "libxstream_offload.hpp"
#include "libxstream_argument.hpp"
#include "libxstream_capture.hpp"
#include "libxstream_context.hpp"
#include <libxstream_begin.h>
#include <algorithm>
#include <libxstream_end.h>
namespace libxstream_offload_internal {
LIBXSTREAM_TARGET(mic) void call(libxstream_function function, libxstream_argument arguments[], char* translation[], size_t arity, int flags)
{
const struct LIBXSTREAM_TARGET(mic) argument_type {
libxstream_argument* m_arguments;
explicit argument_type(libxstream_argument arguments[]): m_arguments(arguments) {}
#if defined(LIBXSTREAM_CALL_BYVALUE)
libxstream_argument::value_union::value_type operator[](size_t i) const { return libxstream_get_value(m_arguments[i]).value; }
#else
const void* operator[](size_t i) const { return libxstream_get_value(m_arguments[i]).const_pointer; }
#endif
} a(arguments);
if (arguments && translation) {
size_t np = 0;
#if defined(__INTEL_COMPILER)
# pragma loop_count min(0), max(LIBXSTREAM_MAX_NARGS), avg(LIBXSTREAM_MAX_NARGS/2)
#endif
for (size_t i = 0; i < arity; ++i) {
if (0 != arguments[i].dims || 0 != (libxstream_argument::kind_output & arguments[i].kind)) {
#if defined(__INTEL_COMPILER)
# pragma forceinline recursive
#endif
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_set_value(arguments[i], translation[np++]));
}
}
}
libxstream_context& context = libxstream_context::instance(arguments, flags);
switch (arity) {
case 0: function(); break;
case 1: function(a[0]); break;
case 2: function(a[0], a[1]); break;
case 3: function(a[0], a[1], a[2]); break;
case 4: function(a[0], a[1], a[2], a[3]); break;
case 5: function(a[0], a[1], a[2], a[3], a[4]); break;
case 6: function(a[0], a[1], a[2], a[3], a[4], a[5]); break;
case 7: function(a[0], a[1], a[2], a[3], a[4], a[5], a[6]); break;
case 8: function(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]); break;
case 9: function(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]); break;
case 10: function(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]); break;
case 11: function(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10]); break;
case 12: function(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11]); break;
case 13: function(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12]); break;
case 14: function(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13]); break;
case 15: function(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14]); break;
case 16: function(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); break;
default: {
LIBXSTREAM_ASSERT(false);
}
}
// mark context as invalid
context.flags = LIBXSTREAM_CALL_EXTERNAL;
#if defined(LIBXSTREAM_DEBUG)
context.signature = 0;
#endif
}
} // namespace libxstream_offload_internal
int libxstream_offload(libxstream_function function, const libxstream_argument signature[], libxstream_stream* stream, int flags)
{
LIBXSTREAM_ASSERT(0 == (LIBXSTREAM_CALL_EXTERNAL & flags));
int result = LIBXSTREAM_ERROR_NONE;
LIBXSTREAM_ASYNC_BEGIN(stream, function, signature) {
LIBXSTREAM_TARGET(mic) /*const*/ libxstream_function fhybrid = 0 == (m_flags & LIBXSTREAM_CALL_NATIVE) ? m_function : 0;
const void *const fnative = reinterpret_cast<const void*>(m_function);
libxstream_argument *const signature = m_signature;
const int flags = m_flags;
size_t arity = 0;
LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_get_arity(m_signature, &arity));
#if defined(LIBXSTREAM_OFFLOAD)
if (0 <= LIBXSTREAM_ASYNC_DEVICE) {
char* p[(LIBXSTREAM_MAX_NARGS)];
unsigned int s = 0;
LIBXSTREAM_ASSERT(LIBXSTREAM_MAX_NARGS <= 8 * sizeof(s));
size_t np = 0;
#if defined(__INTEL_COMPILER)
# pragma loop_count min(0), max(LIBXSTREAM_MAX_NARGS), avg(LIBXSTREAM_MAX_NARGS/2)
#endif
for (size_t i = 0; i < arity; ++i) {
if (0 != m_signature[i].dims) {
p[np] = static_cast<char*>(libxstream_get_value(m_signature[i]).pointer);
++np;
}
else if (0 != (libxstream_argument::kind_output & m_signature[i].kind)) {
p[np] = static_cast<char*>(libxstream_get_value(m_signature[i]).pointer);
s |= ((2 << np) >> 1);
++np;
}
}
# if defined(LIBXSTREAM_DEBUG)
for (size_t i = np; i < (LIBXSTREAM_MAX_NARGS); ++i) p[i] = 0;
# endif
switch (np) {
case 0: {
if (LIBXSTREAM_ASYNC_READY) {
# pragma offload LIBXSTREAM_ASYNC_TARGET_SIGNAL in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1))
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, 0, arity, flags);
}
else {
# pragma offload LIBXSTREAM_ASYNC_TARGET_WAIT in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1))
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, 0, arity, flags);
}
} break;
case 1: {
char *a0 = p[0];
if (LIBXSTREAM_ASYNC_READY) {
# pragma offload LIBXSTREAM_ASYNC_TARGET_SIGNAL in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1)
{
char* translation[] = { a0 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
else {
# pragma offload LIBXSTREAM_ASYNC_TARGET_WAIT in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1)
{
char* translation[] = { a0 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
} break;
case 2: {
char *a0 = p[0], *a1 = p[1];
if (LIBXSTREAM_ASYNC_READY) {
# pragma offload LIBXSTREAM_ASYNC_TARGET_SIGNAL in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2)
{
char* translation[] = { a0, a1 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
else {
# pragma offload LIBXSTREAM_ASYNC_TARGET_WAIT in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2)
{
char* translation[] = { a0, a1 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
} break;
case 3: {
char *a0 = p[0], *a1 = p[1], *a2 = p[2];
if (LIBXSTREAM_ASYNC_READY) {
# pragma offload LIBXSTREAM_ASYNC_TARGET_SIGNAL in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA(a2, s&4)
{
char* translation[] = { a0, a1, a2 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
else {
# pragma offload LIBXSTREAM_ASYNC_TARGET_WAIT in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA(a2, s&4)
{
char* translation[] = { a0, a1, a2 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
} break;
case 4: {
char *a0 = p[0], *a1 = p[1], *a2 = p[2], *a3 = p[3];
if (LIBXSTREAM_ASYNC_READY) {
# pragma offload LIBXSTREAM_ASYNC_TARGET_SIGNAL in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA(a2, s&4) LIBXSTREAM_OFFLOAD_DATA(a3, s&8)
{
char* translation[] = { a0, a1, a2, a3 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
else {
# pragma offload LIBXSTREAM_ASYNC_TARGET_WAIT in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA(a2, s&4) LIBXSTREAM_OFFLOAD_DATA(a3, s&8)
{
char* translation[] = { a0, a1, a2, a3 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
} break;
case 5: {
char *a0 = p[0], *a1 = p[1], *a2 = p[2], *a3 = p[3], *a4 = p[4];
if (LIBXSTREAM_ASYNC_READY) {
# pragma offload LIBXSTREAM_ASYNC_TARGET_SIGNAL in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA(a2, s&4) LIBXSTREAM_OFFLOAD_DATA(a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA(a4, s&16)
{
char* translation[] = { a0, a1, a2, a3, a4 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
else {
# pragma offload LIBXSTREAM_ASYNC_TARGET_WAIT in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA(a2, s&4) LIBXSTREAM_OFFLOAD_DATA(a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA(a4, s&16)
{
char* translation[] = { a0, a1, a2, a3, a4 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
} break;
case 6: {
char *a0 = p[0], *a1 = p[1], *a2 = p[2], *a3 = p[3], *a4 = p[4], *a5 = p[5];
if (LIBXSTREAM_ASYNC_READY) {
# pragma offload LIBXSTREAM_ASYNC_TARGET_SIGNAL in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA(a2, s&4) LIBXSTREAM_OFFLOAD_DATA(a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA(a4, s&16) LIBXSTREAM_OFFLOAD_DATA(a5, s&32)
{
char* translation[] = { a0, a1, a2, a3, a4, a5 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
else {
# pragma offload LIBXSTREAM_ASYNC_TARGET_WAIT in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA(a2, s&4) LIBXSTREAM_OFFLOAD_DATA(a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA(a4, s&16) LIBXSTREAM_OFFLOAD_DATA(a5, s&32)
{
char* translation[] = { a0, a1, a2, a3, a4, a5 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
} break;
case 7: {
char *a0 = p[0], *a1 = p[1], *a2 = p[2], *a3 = p[3], *a4 = p[4], *a5 = p[5], *a6 = p[6];
if (LIBXSTREAM_ASYNC_READY) {
# pragma offload LIBXSTREAM_ASYNC_TARGET_SIGNAL in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA(a2, s&4) LIBXSTREAM_OFFLOAD_DATA(a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA(a4, s&16) LIBXSTREAM_OFFLOAD_DATA(a5, s&32) LIBXSTREAM_OFFLOAD_DATA(a6, s&64)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
else {
# pragma offload LIBXSTREAM_ASYNC_TARGET_WAIT in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA(a2, s&4) LIBXSTREAM_OFFLOAD_DATA(a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA(a4, s&16) LIBXSTREAM_OFFLOAD_DATA(a5, s&32) LIBXSTREAM_OFFLOAD_DATA(a6, s&64)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
} break;
case 8: {
char *a0 = p[0], *a1 = p[1], *a2 = p[2], *a3 = p[3], *a4 = p[4], *a5 = p[5], *a6 = p[6], *a7 = p[7];
if (LIBXSTREAM_ASYNC_READY) {
# pragma offload LIBXSTREAM_ASYNC_TARGET_SIGNAL in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA(a2, s&4) LIBXSTREAM_OFFLOAD_DATA(a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA(a4, s&16) LIBXSTREAM_OFFLOAD_DATA(a5, s&32) LIBXSTREAM_OFFLOAD_DATA(a6, s&64) LIBXSTREAM_OFFLOAD_DATA(a7, s&128)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6, a7 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
else {
# pragma offload LIBXSTREAM_ASYNC_TARGET_WAIT in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA(a2, s&4) LIBXSTREAM_OFFLOAD_DATA(a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA(a4, s&16) LIBXSTREAM_OFFLOAD_DATA(a5, s&32) LIBXSTREAM_OFFLOAD_DATA(a6, s&64) LIBXSTREAM_OFFLOAD_DATA(a7, s&128)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6, a7 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
} break;
case 9: {
char *a0 = p[0], *a1 = p[1], *a2 = p[2], *a3 = p[3], *a4 = p[4], *a5 = p[5], *a6 = p[6], *a7 = p[7], *a8 = p[8];
if (LIBXSTREAM_ASYNC_READY) {
# pragma offload LIBXSTREAM_ASYNC_TARGET_SIGNAL in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA(a2, s&4) LIBXSTREAM_OFFLOAD_DATA(a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA(a4, s&16) LIBXSTREAM_OFFLOAD_DATA(a5, s&32) LIBXSTREAM_OFFLOAD_DATA(a6, s&64) LIBXSTREAM_OFFLOAD_DATA(a7, s&128) \
LIBXSTREAM_OFFLOAD_DATA(a8, s&256)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6, a7, a8 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
else {
# pragma offload LIBXSTREAM_ASYNC_TARGET_WAIT in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA(a2, s&4) LIBXSTREAM_OFFLOAD_DATA(a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA(a4, s&16) LIBXSTREAM_OFFLOAD_DATA(a5, s&32) LIBXSTREAM_OFFLOAD_DATA(a6, s&64) LIBXSTREAM_OFFLOAD_DATA(a7, s&128) \
LIBXSTREAM_OFFLOAD_DATA(a8, s&256)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6, a7, a8 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
} break;
case 10: {
char *a0 = p[0], *a1 = p[1], *a2 = p[2], *a3 = p[3], *a4 = p[4], *a5 = p[5], *a6 = p[6], *a7 = p[7], *a8 = p[8], *a9 = p[9];
if (LIBXSTREAM_ASYNC_READY) {
# pragma offload LIBXSTREAM_ASYNC_TARGET_SIGNAL in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA(a2, s&4) LIBXSTREAM_OFFLOAD_DATA(a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA(a4, s&16) LIBXSTREAM_OFFLOAD_DATA(a5, s&32) LIBXSTREAM_OFFLOAD_DATA(a6, s&64) LIBXSTREAM_OFFLOAD_DATA(a7, s&128) \
LIBXSTREAM_OFFLOAD_DATA(a8, s&256) LIBXSTREAM_OFFLOAD_DATA(a9, s&512)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
else {
# pragma offload LIBXSTREAM_ASYNC_TARGET_WAIT in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA(a2, s&4) LIBXSTREAM_OFFLOAD_DATA(a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA(a4, s&16) LIBXSTREAM_OFFLOAD_DATA(a5, s&32) LIBXSTREAM_OFFLOAD_DATA(a6, s&64) LIBXSTREAM_OFFLOAD_DATA(a7, s&128) \
LIBXSTREAM_OFFLOAD_DATA(a8, s&256) LIBXSTREAM_OFFLOAD_DATA(a9, s&512)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
} break;
case 11: {
char *a0 = p[0], *a1 = p[1], *a2 = p[2], *a3 = p[3], *a4 = p[4], *a5 = p[5], *a6 = p[6], *a7 = p[7], *a8 = p[8], *a9 = p[9], *a10 = p[10];
if (LIBXSTREAM_ASYNC_READY) {
# pragma offload LIBXSTREAM_ASYNC_TARGET_SIGNAL in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA( a2, s&4) LIBXSTREAM_OFFLOAD_DATA(a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA(a4, s&16) LIBXSTREAM_OFFLOAD_DATA(a5, s&32) LIBXSTREAM_OFFLOAD_DATA( a6, s&64) LIBXSTREAM_OFFLOAD_DATA(a7, s&128) \
LIBXSTREAM_OFFLOAD_DATA(a8, s&256) LIBXSTREAM_OFFLOAD_DATA(a9, s&512) LIBXSTREAM_OFFLOAD_DATA(a10, s&1024)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
else {
# pragma offload LIBXSTREAM_ASYNC_TARGET_WAIT in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA( a2, s&4) LIBXSTREAM_OFFLOAD_DATA(a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA(a4, s&16) LIBXSTREAM_OFFLOAD_DATA(a5, s&32) LIBXSTREAM_OFFLOAD_DATA( a6, s&64) LIBXSTREAM_OFFLOAD_DATA(a7, s&128) \
LIBXSTREAM_OFFLOAD_DATA(a8, s&256) LIBXSTREAM_OFFLOAD_DATA(a9, s&512) LIBXSTREAM_OFFLOAD_DATA(a10, s&1024)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
} break;
case 12: {
char *a0 = p[0], *a1 = p[1], *a2 = p[2], *a3 = p[3], *a4 = p[4], *a5 = p[5], *a6 = p[6], *a7 = p[7];
char *a8 = p[8], *a9 = p[9], *a10 = p[10], *a11 = p[11];
if (LIBXSTREAM_ASYNC_READY) {
# pragma offload LIBXSTREAM_ASYNC_TARGET_SIGNAL in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA( a2, s&4) LIBXSTREAM_OFFLOAD_DATA( a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA(a4, s&16) LIBXSTREAM_OFFLOAD_DATA(a5, s&32) LIBXSTREAM_OFFLOAD_DATA( a6, s&64) LIBXSTREAM_OFFLOAD_DATA( a7, s&128) \
LIBXSTREAM_OFFLOAD_DATA(a8, s&256) LIBXSTREAM_OFFLOAD_DATA(a9, s&512) LIBXSTREAM_OFFLOAD_DATA(a10, s&1024) LIBXSTREAM_OFFLOAD_DATA(a11, s&2048)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
else {
# pragma offload LIBXSTREAM_ASYNC_TARGET_WAIT in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA(a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA( a2, s&4) LIBXSTREAM_OFFLOAD_DATA( a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA(a4, s&16) LIBXSTREAM_OFFLOAD_DATA(a5, s&32) LIBXSTREAM_OFFLOAD_DATA( a6, s&64) LIBXSTREAM_OFFLOAD_DATA( a7, s&128) \
LIBXSTREAM_OFFLOAD_DATA(a8, s&256) LIBXSTREAM_OFFLOAD_DATA(a9, s&512) LIBXSTREAM_OFFLOAD_DATA(a10, s&1024) LIBXSTREAM_OFFLOAD_DATA(a11, s&2048)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
} break;
case 13: {
char *a0 = p[0], *a1 = p[1], *a2 = p[2], *a3 = p[3], *a4 = p[4], *a5 = p[5], *a6 = p[6], *a7 = p[7];
char *a8 = p[8], *a9 = p[9], *a10 = p[10], *a11 = p[11], *a12 = p[12];
if (LIBXSTREAM_ASYNC_READY) {
# pragma offload LIBXSTREAM_ASYNC_TARGET_SIGNAL in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA( a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA( a2, s&4) LIBXSTREAM_OFFLOAD_DATA( a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA( a4, s&16) LIBXSTREAM_OFFLOAD_DATA(a5, s&32) LIBXSTREAM_OFFLOAD_DATA( a6, s&64) LIBXSTREAM_OFFLOAD_DATA( a7, s&128) \
LIBXSTREAM_OFFLOAD_DATA( a8, s&256) LIBXSTREAM_OFFLOAD_DATA(a9, s&512) LIBXSTREAM_OFFLOAD_DATA(a10, s&1024) LIBXSTREAM_OFFLOAD_DATA(a11, s&2048) \
LIBXSTREAM_OFFLOAD_DATA(a12, s&4096)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
else {
# pragma offload LIBXSTREAM_ASYNC_TARGET_WAIT in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA( a0, s&1) LIBXSTREAM_OFFLOAD_DATA(a1, s&2) LIBXSTREAM_OFFLOAD_DATA( a2, s&4) LIBXSTREAM_OFFLOAD_DATA( a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA( a4, s&16) LIBXSTREAM_OFFLOAD_DATA(a5, s&32) LIBXSTREAM_OFFLOAD_DATA( a6, s&64) LIBXSTREAM_OFFLOAD_DATA( a7, s&128) \
LIBXSTREAM_OFFLOAD_DATA( a8, s&256) LIBXSTREAM_OFFLOAD_DATA(a9, s&512) LIBXSTREAM_OFFLOAD_DATA(a10, s&1024) LIBXSTREAM_OFFLOAD_DATA(a11, s&2048) \
LIBXSTREAM_OFFLOAD_DATA(a12, s&4096)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
} break;
case 14: {
char *a0 = p[0], *a1 = p[1], *a2 = p[2], *a3 = p[3], *a4 = p[4], *a5 = p[5], *a6 = p[6], *a7 = p[7];
char *a8 = p[8], *a9 = p[9], *a10 = p[10], *a11 = p[11], *a12 = p[12], *a13 = p[13];
if (LIBXSTREAM_ASYNC_READY) {
# pragma offload LIBXSTREAM_ASYNC_TARGET_SIGNAL in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA( a0, s&1) LIBXSTREAM_OFFLOAD_DATA( a1, s&2) LIBXSTREAM_OFFLOAD_DATA( a2, s&4) LIBXSTREAM_OFFLOAD_DATA( a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA( a4, s&16) LIBXSTREAM_OFFLOAD_DATA( a5, s&32) LIBXSTREAM_OFFLOAD_DATA( a6, s&64) LIBXSTREAM_OFFLOAD_DATA( a7, s&128) \
LIBXSTREAM_OFFLOAD_DATA( a8, s&256) LIBXSTREAM_OFFLOAD_DATA( a9, s&512) LIBXSTREAM_OFFLOAD_DATA(a10, s&1024) LIBXSTREAM_OFFLOAD_DATA(a11, s&2048) \
LIBXSTREAM_OFFLOAD_DATA(a12, s&4096) LIBXSTREAM_OFFLOAD_DATA(a13, s&8192)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
else {
# pragma offload LIBXSTREAM_ASYNC_TARGET_WAIT in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA( a0, s&1) LIBXSTREAM_OFFLOAD_DATA( a1, s&2) LIBXSTREAM_OFFLOAD_DATA( a2, s&4) LIBXSTREAM_OFFLOAD_DATA( a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA( a4, s&16) LIBXSTREAM_OFFLOAD_DATA( a5, s&32) LIBXSTREAM_OFFLOAD_DATA( a6, s&64) LIBXSTREAM_OFFLOAD_DATA( a7, s&128) \
LIBXSTREAM_OFFLOAD_DATA( a8, s&256) LIBXSTREAM_OFFLOAD_DATA( a9, s&512) LIBXSTREAM_OFFLOAD_DATA(a10, s&1024) LIBXSTREAM_OFFLOAD_DATA(a11, s&2048) \
LIBXSTREAM_OFFLOAD_DATA(a12, s&4096) LIBXSTREAM_OFFLOAD_DATA(a13, s&8192)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
} break;
case 15: {
char *a0 = p[0], *a1 = p[1], *a2 = p[2], *a3 = p[3], *a4 = p[4], *a5 = p[5], *a6 = p[6], *a7 = p[7];
char *a8 = p[8], *a9 = p[9], *a10 = p[10], *a11 = p[11], *a12 = p[12], *a13 = p[13], *a14 = p[14];
if (LIBXSTREAM_ASYNC_READY) {
# pragma offload LIBXSTREAM_ASYNC_TARGET_SIGNAL in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA( a0, s&1) LIBXSTREAM_OFFLOAD_DATA( a1, s&2) LIBXSTREAM_OFFLOAD_DATA( a2, s&4) LIBXSTREAM_OFFLOAD_DATA( a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA( a4, s&16) LIBXSTREAM_OFFLOAD_DATA( a5, s&32) LIBXSTREAM_OFFLOAD_DATA( a6, s&64) LIBXSTREAM_OFFLOAD_DATA( a7, s&128) \
LIBXSTREAM_OFFLOAD_DATA( a8, s&256) LIBXSTREAM_OFFLOAD_DATA( a9, s&512) LIBXSTREAM_OFFLOAD_DATA(a10, s&1024) LIBXSTREAM_OFFLOAD_DATA(a11, s&2048) \
LIBXSTREAM_OFFLOAD_DATA(a12, s&4096) LIBXSTREAM_OFFLOAD_DATA(a13, s&8192) LIBXSTREAM_OFFLOAD_DATA(a14, s&16384)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
else {
# pragma offload LIBXSTREAM_ASYNC_TARGET_WAIT in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA( a0, s&1) LIBXSTREAM_OFFLOAD_DATA( a1, s&2) LIBXSTREAM_OFFLOAD_DATA( a2, s&4) LIBXSTREAM_OFFLOAD_DATA( a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA( a4, s&16) LIBXSTREAM_OFFLOAD_DATA( a5, s&32) LIBXSTREAM_OFFLOAD_DATA( a6, s&64) LIBXSTREAM_OFFLOAD_DATA( a7, s&128) \
LIBXSTREAM_OFFLOAD_DATA( a8, s&256) LIBXSTREAM_OFFLOAD_DATA( a9, s&512) LIBXSTREAM_OFFLOAD_DATA(a10, s&1024) LIBXSTREAM_OFFLOAD_DATA(a11, s&2048) \
LIBXSTREAM_OFFLOAD_DATA(a12, s&4096) LIBXSTREAM_OFFLOAD_DATA(a13, s&8192) LIBXSTREAM_OFFLOAD_DATA(a14, s&16384)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
} break;
case 16: {
char *a0 = p[0], *a1 = p[1], *a2 = p[2], *a3 = p[3], *a4 = p[4], *a5 = p[5], *a6 = p[6], *a7 = p[7];
char *a8 = p[8], *a9 = p[9], *a10 = p[10], *a11 = p[11], *a12 = p[12], *a13 = p[13], *a14 = p[14], *a15 = p[15];
if (LIBXSTREAM_ASYNC_READY) {
# pragma offload LIBXSTREAM_ASYNC_TARGET_SIGNAL in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA( a0, s&1) LIBXSTREAM_OFFLOAD_DATA( a1, s&2) LIBXSTREAM_OFFLOAD_DATA( a2, s&4) LIBXSTREAM_OFFLOAD_DATA( a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA( a4, s&16) LIBXSTREAM_OFFLOAD_DATA( a5, s&32) LIBXSTREAM_OFFLOAD_DATA( a6, s&64) LIBXSTREAM_OFFLOAD_DATA( a7, s&128) \
LIBXSTREAM_OFFLOAD_DATA( a8, s&256) LIBXSTREAM_OFFLOAD_DATA( a9, s&512) LIBXSTREAM_OFFLOAD_DATA(a10, s&1024) LIBXSTREAM_OFFLOAD_DATA(a11, s&2048) \
LIBXSTREAM_OFFLOAD_DATA(a12, s&4096) LIBXSTREAM_OFFLOAD_DATA(a13, s&8192) LIBXSTREAM_OFFLOAD_DATA(a14, s&16384) LIBXSTREAM_OFFLOAD_DATA(a15, s&32768)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
else {
# pragma offload LIBXSTREAM_ASYNC_TARGET_WAIT in(fhybrid, fnative, arity, flags) in(signature: length(arity + 1)) \
LIBXSTREAM_OFFLOAD_DATA( a0, s&1) LIBXSTREAM_OFFLOAD_DATA( a1, s&2) LIBXSTREAM_OFFLOAD_DATA( a2, s&4) LIBXSTREAM_OFFLOAD_DATA( a3, s&8) \
LIBXSTREAM_OFFLOAD_DATA( a4, s&16) LIBXSTREAM_OFFLOAD_DATA( a5, s&32) LIBXSTREAM_OFFLOAD_DATA( a6, s&64) LIBXSTREAM_OFFLOAD_DATA( a7, s&128) \
LIBXSTREAM_OFFLOAD_DATA( a8, s&256) LIBXSTREAM_OFFLOAD_DATA( a9, s&512) LIBXSTREAM_OFFLOAD_DATA(a10, s&1024) LIBXSTREAM_OFFLOAD_DATA(a11, s&2048) \
LIBXSTREAM_OFFLOAD_DATA(a12, s&4096) LIBXSTREAM_OFFLOAD_DATA(a13, s&8192) LIBXSTREAM_OFFLOAD_DATA(a14, s&16384) LIBXSTREAM_OFFLOAD_DATA(a15, s&32768)
{
char* translation[] = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 };
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, translation, arity, flags);
}
}
} break;
default: {
LIBXSTREAM_CHECK_CALL_ASSERT(status(LIBXSTREAM_ERROR_CONDITION));
}
}
}
else
#endif
{
libxstream_offload_internal::call(fhybrid ? fhybrid : reinterpret_cast<libxstream_function>(fnative), signature, 0, arity, flags);
}
}
LIBXSTREAM_ASYNC_END(flags, result);
return result;
}
#endif // defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)

View file

@ -1,42 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#ifndef LIBXSTREAM_OFFLOAD_HPP
#define LIBXSTREAM_OFFLOAD_HPP
#include <libxstream.h>
#if defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
int libxstream_offload(libxstream_function function, const libxstream_argument signature[], libxstream_stream* stream, int flags);
#endif // defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
#endif // LIBXSTREAM_OFFLOAD_HPP

View file

@ -1,607 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#if defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
#include "libxstream_stream.hpp"
#include "libxstream_capture.hpp"
#include "libxstream_event.hpp"
#include <libxstream_begin.h>
#include <algorithm>
#include <string>
#include <cstdio>
#if defined(LIBXSTREAM_STDFEATURES)
# include <atomic>
#endif
#include <libxstream_end.h>
// allows to wait for an event issued prior to the pending signal
//#define LIBXSTREAM_STREAM_WAIT_PAST
// unlocking the stream is only allowed for the thread that locked
//#define LIBXSTREAM_STREAM_UNLOCK_OWNER
namespace libxstream_stream_internal {
class registry_type {
public:
registry_type()
: m_istreams(0)
#if !defined(LIBXSTREAM_STDFEATURES)
, m_lock(libxstream_lock_create())
#endif
{
std::fill_n(m_signals, LIBXSTREAM_MAX_NDEVICES, 0);
std::fill_n(m_streams, LIBXSTREAM_MAX_NDEVICES * LIBXSTREAM_MAX_NSTREAMS, static_cast<libxstream_stream*>(0));
}
~registry_type() {
const size_t n = max_nstreams();
for (size_t i = 0; i < n; ++i) {
#if defined(LIBXSTREAM_DEBUG)
if (0 != m_streams[i]) {
LIBXSTREAM_PRINT_WARN("dangling stream \"%s\"!", m_streams[i]->name());
}
#endif
libxstream_stream_destroy(m_streams[i]);
}
#if !defined(LIBXSTREAM_STDFEATURES)
libxstream_lock_destroy(m_lock);
#endif
}
public:
libxstream_stream** allocate() {
#if !defined(LIBXSTREAM_STDFEATURES)
libxstream_lock_acquire(m_lock);
#endif
libxstream_stream** i = m_streams + (m_istreams++ % (LIBXSTREAM_MAX_NDEVICES * LIBXSTREAM_MAX_NSTREAMS));
while (0 != *i) i = m_streams + (m_istreams++ % (LIBXSTREAM_MAX_NDEVICES * LIBXSTREAM_MAX_NSTREAMS));
#if !defined(LIBXSTREAM_STDFEATURES)
libxstream_lock_release(m_lock);
#endif
return i;
}
size_t max_nstreams() const {
return std::min<size_t>(m_istreams, LIBXSTREAM_MAX_NDEVICES * LIBXSTREAM_MAX_NSTREAMS);
}
size_t nstreams(int device) const {
const size_t n = max_nstreams();
size_t result = 0;
for (size_t i = 0; i < n; ++i) {
result += (0 != m_streams[i] && m_streams[i]->device() == device) ? 1 : 0;
}
return result;
}
size_t nstreams() const {
const size_t n = max_nstreams();
size_t result = 0;
for (size_t i = 0; i < n; ++i) {
result += 0 != m_streams[i] ? 1 : 0;
}
return result;
}
libxstream_signal& signal(int device) {
LIBXSTREAM_ASSERT(-1 <= device && device <= LIBXSTREAM_MAX_NDEVICES);
return m_signals[device+1];
}
libxstream_stream** streams() {
return m_streams;
}
int enqueue(libxstream_event& event, const libxstream_stream* exclude) {
LIBXSTREAM_ASSERT(0 == event.expected());
int result = LIBXSTREAM_ERROR_NONE;
const size_t n = max_nstreams();
bool reset = true;
for (size_t i = 0; i < n; ++i) {
libxstream_stream *const stream = m_streams[i];
if (stream != exclude) {
result = event.enqueue(*stream, reset);
LIBXSTREAM_CHECK_ERROR(result);
reset = false;
}
}
if (reset) {
result = event.reset();
}
return result;
}
int sync(int device) {
const size_t n = max_nstreams();
for (size_t i = 0; i < n; ++i) {
if (libxstream_stream *const stream = m_streams[i]) {
const int stream_device = stream->device();
if (stream_device == device) {
const int result = stream->wait(0);
LIBXSTREAM_CHECK_ERROR(result);
}
}
}
return LIBXSTREAM_ERROR_NONE;
}
int sync() {
const size_t n = max_nstreams();
for (size_t i = 0; i < n; ++i) {
if (libxstream_stream *const stream = m_streams[i]) {
const int result = stream->wait(0);
LIBXSTREAM_CHECK_ERROR(result);
}
}
return LIBXSTREAM_ERROR_NONE;
}
#if !defined(LIBXSTREAM_STDFEATURES)
libxstream_lock* lock() { return m_lock; }
#endif
private:
// not necessary to be device-specific due to single-threaded offload
libxstream_signal m_signals[LIBXSTREAM_MAX_NDEVICES + 1];
libxstream_stream* m_streams[LIBXSTREAM_MAX_NDEVICES*LIBXSTREAM_MAX_NSTREAMS];
#if defined(LIBXSTREAM_STDFEATURES)
std::atomic<size_t> m_istreams;
#else
size_t m_istreams;
libxstream_lock* m_lock;
#endif
} registry;
template<typename A, typename E, typename D>
bool atomic_compare_exchange(A& atomic, E& expected, D desired)
{
#if defined(LIBXSTREAM_STDFEATURES)
const bool result = std::atomic_compare_exchange_weak(&atomic, &expected, desired);
#elif defined(_OPENMP)
bool result = false;
# pragma omp critical
{
result = atomic == expected;
if (result) {
atomic = desired;
}
else {
expected = atomic;
}
}
#else // generic
bool result = false;
libxstream_lock_acquire(registry.lock());
result = atomic == expected;
if (result) {
atomic = desired;
}
else {
expected = atomic;
}
libxstream_lock_release(registry.lock());
#endif
return result;
}
template<typename A, typename T>
T atomic_store(A& atomic, T value)
{
T result = value;
#if defined(LIBXSTREAM_STDFEATURES)
result = std::atomic_exchange(&atomic, value);
#elif defined(_OPENMP)
# pragma omp critical
{
result = atomic;
atomic = value;
}
#else // generic
libxstream_lock_acquire(registry.lock());
result = atomic;
atomic = value;
libxstream_lock_release(registry.lock());
#endif
return result;
}
} // namespace libxstream_stream_internal
/*static*/int libxstream_stream::enqueue(libxstream_event& event, const libxstream_stream* exclude)
{
return libxstream_stream_internal::registry.enqueue(event, exclude);
}
/*static*/int libxstream_stream::sync(int device)
{
return libxstream_stream_internal::registry.sync(device);
}
/*static*/int libxstream_stream::sync()
{
return libxstream_stream_internal::registry.sync();
}
libxstream_stream::libxstream_stream(int device, int demux, int priority, const char* name)
#if defined(LIBXSTREAM_STDFEATURES)
: m_thread(new std::atomic<int>(-1))
#else
: m_thread(new int(-1))
#endif
#if !(defined(LIBXSTREAM_THREADLOCAL_SIGNALS) && defined(LIBXSTREAM_ASYNC) && (0 != (2*LIBXSTREAM_ASYNC+1)/2))
, m_signal(0), m_pending(&m_signal)
#endif
#if defined(LIBXSTREAM_LOCK_RETRY) && (0 < (LIBXSTREAM_LOCK_RETRY))
, m_begin(0), m_end(0)
#endif
, m_demux(demux)
, m_device(device), m_priority(priority)
#if defined(LIBXSTREAM_OFFLOAD) && defined(LIBXSTREAM_ASYNC) && (2 == (2*LIBXSTREAM_ASYNC+1)/2)
, m_handle(0) // lazy creation
, m_npartitions(0)
#endif
{
libxstream_use_sink(name);
#if defined(LIBXSTREAM_THREADLOCAL_SIGNALS) && defined(LIBXSTREAM_ASYNC) && (0 != (2*LIBXSTREAM_ASYNC+1)/2)
std::fill_n(m_pending, LIBXSTREAM_MAX_NTHREADS, static_cast<libxstream_signal>(0));
#endif
#if defined(LIBXSTREAM_PRINT)
if (name && 0 != *name) {
const size_t length = std::min(std::char_traits<char>::length(name), sizeof(m_name) - 1);
std::copy(name, name + length, m_name);
m_name[length] = 0;
}
else {
m_name[0] = 0;
}
#endif
using namespace libxstream_stream_internal;
libxstream_stream* *const slot = libxstream_stream_internal::registry.allocate();
*slot = this;
}
libxstream_stream::~libxstream_stream()
{
using namespace libxstream_stream_internal;
libxstream_stream* *const end = registry.streams() + registry.max_nstreams();
libxstream_stream* *const stream = std::find(registry.streams(), end, this);
LIBXSTREAM_ASSERT(stream != end);
*stream = 0; // unregister stream
#if defined(LIBXSTREAM_STDFEATURES)
delete static_cast<std::atomic<int>*>(m_thread);
#else
delete static_cast<int*>(m_thread);
#endif
#if defined(LIBXSTREAM_OFFLOAD) && (0 != LIBXSTREAM_OFFLOAD) && !defined(__MIC__) && defined(LIBXSTREAM_ASYNC) && (2 == (2*LIBXSTREAM_ASYNC+1)/2)
if (0 != m_handle) {
_Offload_stream_destroy(m_device, m_handle);
}
#endif
}
libxstream_signal libxstream_stream::signal() const
{
return ++libxstream_stream_internal::registry.signal(m_device);
}
int libxstream_stream::wait(libxstream_signal signal)
{
int result = LIBXSTREAM_ERROR_NONE;
LIBXSTREAM_ASYNC_BEGIN(this, m_pending, signal)
{
libxstream_signal *const pending_signals = ptr<libxstream_signal,0>();
const libxstream_signal signal = val<const libxstream_signal,1>();
#if defined(LIBXSTREAM_THREADLOCAL_SIGNALS) && defined(LIBXSTREAM_ASYNC) && (0 != (2*LIBXSTREAM_ASYNC+1)/2)
const int nthreads = static_cast<int>(nthreads_active());
for (int i = 0; i < nthreads; ++i)
#else
const int i = thread();
#endif
{
const libxstream_signal pending_signal = pending_signals[i];
if (0 != pending_signal) {
#if defined(LIBXSTREAM_OFFLOAD) && defined(LIBXSTREAM_ASYNC) && (0 != (2*LIBXSTREAM_ASYNC+1)/2)
if (0 <= LIBXSTREAM_ASYNC_DEVICE) {
# if defined(LIBXSTREAM_STREAM_WAIT_PAST)
const libxstream_signal wait_pending = 0 != signal ? signal : pending_signal;
# else
const libxstream_signal wait_pending = pending_signal;
# endif
# pragma offload_wait LIBXSTREAM_ASYNC_TARGET wait(wait_pending)
}
#endif
if (0 == signal) {
pending_signals[i] = 0;
}
#if defined(LIBXSTREAM_STREAM_WAIT_PAST)
else {
i = nthreads; // break
}
#endif
}
}
if (0 != signal) {
#if defined(LIBXSTREAM_THREADLOCAL_SIGNALS) && defined(LIBXSTREAM_ASYNC) && (0 != (2*LIBXSTREAM_ASYNC+1)/2)
for (int i = 0; i < nthreads; ++i)
#else
const int i = thread();
#endif
{
if (signal == pending_signals[i]) {
pending_signals[i] = 0;
}
}
}
}
LIBXSTREAM_ASYNC_END(LIBXSTREAM_CALL_DEFAULT | LIBXSTREAM_CALL_WAIT | LIBXSTREAM_CALL_UNLOCK, result);
return result;
}
void libxstream_stream::pending(int thread, libxstream_signal signal)
{
#if defined(LIBXSTREAM_THREADLOCAL_SIGNALS) && defined(LIBXSTREAM_ASYNC) && (0 != (2*LIBXSTREAM_ASYNC+1)/2)
LIBXSTREAM_ASSERT(0 <= thread && thread < LIBXSTREAM_MAX_NTHREADS);
m_pending[thread] = signal;
#else
libxstream_use_sink(&thread);
LIBXSTREAM_ASSERT(0 == thread);
m_signal = signal;
#endif
}
libxstream_signal libxstream_stream::pending(int thread) const
{
#if defined(LIBXSTREAM_THREADLOCAL_SIGNALS) && defined(LIBXSTREAM_ASYNC) && (0 != (2*LIBXSTREAM_ASYNC+1)/2)
LIBXSTREAM_ASSERT(0 <= thread && thread < LIBXSTREAM_MAX_NTHREADS);
const libxstream_signal signal = m_pending[thread];
#else
libxstream_use_sink(&thread);
LIBXSTREAM_ASSERT(0 == thread);
const libxstream_signal signal = m_signal;
#endif
return signal;
}
int libxstream_stream::thread() const
{
LIBXSTREAM_ASSERT(m_thread);
#if defined(LIBXSTREAM_STDFEATURES)
return *static_cast<std::atomic<int>*>(m_thread);
#else
return *static_cast<int*>(m_thread);
#endif
}
void libxstream_stream::begin()
{
#if defined(LIBXSTREAM_LOCK_RETRY) && (0 < (LIBXSTREAM_LOCK_RETRY))
# if defined(LIBXSTREAM_STREAM_UNLOCK_OWNER)
if (thread() == this_thread_id())
# endif
{
++m_begin;
}
#endif
}
void libxstream_stream::end()
{
#if defined(LIBXSTREAM_LOCK_RETRY) && (0 < (LIBXSTREAM_LOCK_RETRY))
# if defined(LIBXSTREAM_STREAM_UNLOCK_OWNER)
if (thread() == this_thread_id())
# endif
{
++m_end;
}
#endif
}
void libxstream_stream::lock(bool retry)
{
const int this_thread = this_thread_id();
#if defined(LIBXSTREAM_STDFEATURES)
std::atomic<int> *const stream_thread = static_cast<std::atomic<int>*>(m_thread);
#else
volatile int *const stream_thread = static_cast<volatile int*>(m_thread);
#endif
int lock_thread = *stream_thread;
if (this_thread != lock_thread) {
int unlocked = -1;
#if defined(LIBXSTREAM_LOCK_RETRY) && (0 < (LIBXSTREAM_LOCK_RETRY))
size_t thread_begin = m_begin, thread_end = m_end, nretry = 0;
# if defined(LIBXSTREAM_PRINT)
size_t delay = 0;
# endif
if (retry) {
while (!libxstream_stream_internal::atomic_compare_exchange(*stream_thread, unlocked, this_thread)) {
static /*const*/ size_t sleep_ms = (LIBXSTREAM_WAIT_LOCK_MS) / (LIBXSTREAM_LOCK_RETRY);
if ((LIBXSTREAM_LOCK_RETRY) > nretry || m_begin != m_end) {
nretry += (thread_begin == m_begin && thread_end == m_end) ? 1 : 0;
if (0 < sleep_ms) {
this_thread_sleep(sleep_ms);
}
else {
this_thread_yield();
}
thread_begin = m_begin;
thread_end = m_end;
unlocked = -1;
}
else {
unlocked = lock_thread != *stream_thread ? -1 : lock_thread;
lock_thread = *stream_thread;
# if defined(LIBXSTREAM_PRINT)
delay += nretry * sleep_ms;
# endif
nretry = 0;
}
}
if (-1 != unlocked) {
# if defined(LIBXSTREAM_PRINT)
LIBXSTREAM_PRINT_WARN("libxstream_stream_unlock: stream=0x%llx released by thread=%i with delay=%lu ms",
reinterpret_cast<unsigned long long>(this), this_thread, static_cast<unsigned long>(delay));
# else
LIBXSTREAM_PRINT_WARN("libxstream_stream_unlock: stream=0x%llx released by thread=%i",
reinterpret_cast<unsigned long long>(this), this_thread);
# endif
}
m_begin = 0;
m_end = 0;
}
else
#endif
{
while (!libxstream_stream_internal::atomic_compare_exchange(*stream_thread, unlocked, this_thread)) {
this_thread_yield();
unlocked = -1;
}
}
LIBXSTREAM_ASSERT(this_thread == *stream_thread);
LIBXSTREAM_PRINT_INFO("libxstream_stream_lock: stream=0x%llx acquired by thread=%i",
reinterpret_cast<unsigned long long>(this), this_thread);
}
}
void libxstream_stream::unlock()
{
#if defined(LIBXSTREAM_STDFEATURES)
std::atomic<int> *const stream_thread = static_cast<std::atomic<int>*>(m_thread);
#else
volatile int *const stream_thread = static_cast<volatile int*>(m_thread);
#endif
#if defined(LIBXSTREAM_STREAM_UNLOCK_OWNER)
int locked = this_thread_id();
if (libxstream_stream_internal::atomic_compare_exchange(*stream_thread, locked, -1)) {
#else
if (libxstream_stream_internal::atomic_store(*stream_thread, -1)) {
#endif
LIBXSTREAM_PRINT_INFO("libxstream_stream_unlock: stream=0x%llx released by thread=%i",
reinterpret_cast<unsigned long long>(this), this_thread_id());
}
}
#if defined(LIBXSTREAM_OFFLOAD) && (0 != LIBXSTREAM_OFFLOAD) && defined(LIBXSTREAM_ASYNC) && (2 == (2*LIBXSTREAM_ASYNC+1)/2)
_Offload_stream libxstream_stream::handle() const
{
const size_t nstreams = libxstream_stream_internal::registry.nstreams(m_device);
if (nstreams != m_npartitions) {
if (0 != m_handle) {
const_cast<libxstream_stream*>(this)->wait(0); // complete pending operations on old stream
_Offload_stream_destroy(m_device, m_handle);
}
// TODO: implement device discovery (number of threads)
const size_t nthreads = 224;
// TODO: implement stream priorities (weighting)
m_handle = _Offload_stream_create(m_device, static_cast<int>(nthreads / nstreams));
m_npartitions = nstreams;
}
return m_handle;
}
#endif
#if defined(LIBXSTREAM_PRINT)
const char* libxstream_stream::name() const
{
return m_name;
}
#endif
const libxstream_stream* cast_to_stream(const void* stream)
{
return static_cast<const libxstream_stream*>(stream);
}
libxstream_stream* cast_to_stream(void* stream)
{
return static_cast<libxstream_stream*>(stream);
}
const libxstream_stream* cast_to_stream(const libxstream_stream* stream)
{
return stream;
}
libxstream_stream* cast_to_stream(libxstream_stream* stream)
{
return stream;
}
const libxstream_stream* cast_to_stream(const libxstream_stream& stream)
{
return &stream;
}
libxstream_stream* cast_to_stream(libxstream_stream& stream)
{
return &stream;
}
#endif // defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)

View file

@ -1,136 +0,0 @@
/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation **
** All rights reserved. **
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. Neither the name of the copyright holder nor the names of its **
** contributors may be used to endorse or promote products derived **
** from this software without specific prior written permission. **
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#ifndef LIBXSTREAM_STREAM_HPP
#define LIBXSTREAM_STREAM_HPP
#include "libxstream.hpp"
#if defined(LIBXSTREAM_OFFLOAD) && (0 != LIBXSTREAM_OFFLOAD)
# include <offload.h>
#endif
#if defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
struct libxstream_event;
struct libxstream_stream {
public:
static int enqueue(libxstream_event& event, const libxstream_stream* exclude = 0);
static int sync(int device);
static int sync();
public:
libxstream_stream(int device,
/**
* Controls "demuxing" threads and streams i.e., when multiple threads are queuing into the same stream.
* demux<0: automatic (LIBXSTREAM guesses locks incl. deadlock resolution using LIBXSTREAM_LOCK_RETRY)
* demux=0: disabled (application is supposed to call libxstream_stream_lock/libxstream_stream_unlock)
* demux>0: enabled (application is supposed to use correct stream synchronization)
*/
int demux,
int priority, const char* name);
~libxstream_stream();
public:
int demux() const { return m_demux; }
int device() const { return m_device; }
int priority() const { return m_priority; }
libxstream_signal signal() const;
int wait(libxstream_signal signal);
void pending(int thread, libxstream_signal signal);
libxstream_signal pending(int thread) const;
int thread() const;
void begin();
void end();
void lock(bool retry);
void unlock();
#if defined(LIBXSTREAM_OFFLOAD) && (0 != LIBXSTREAM_OFFLOAD) && defined(LIBXSTREAM_ASYNC) && (2 == (2*LIBXSTREAM_ASYNC+1)/2)
_Offload_stream handle() const;
#endif
#if defined(LIBXSTREAM_PRINT)
const char* name() const;
#endif
private:
libxstream_stream(const libxstream_stream& other);
libxstream_stream& operator=(const libxstream_stream& other);
private:
#if defined(LIBXSTREAM_THREADLOCAL_SIGNALS) && defined(LIBXSTREAM_ASYNC) && (0 != (2*LIBXSTREAM_ASYNC+1)/2)
libxstream_signal m_pending[LIBXSTREAM_MAX_NTHREADS];
#endif
#if defined(LIBXSTREAM_PRINT)
char m_name[128];
#endif
void* m_thread;
#if !(defined(LIBXSTREAM_THREADLOCAL_SIGNALS) && defined(LIBXSTREAM_ASYNC) && (0 != (2*LIBXSTREAM_ASYNC+1)/2))
libxstream_signal m_signal, *const m_pending;
#endif
#if defined(LIBXSTREAM_LOCK_RETRY) && (0 < (LIBXSTREAM_LOCK_RETRY))
size_t m_begin, m_end;
#endif
int m_demux;
int m_device;
int m_priority;
#if defined(LIBXSTREAM_OFFLOAD) && (0 != LIBXSTREAM_OFFLOAD) && defined(LIBXSTREAM_ASYNC) && (2 == (2*LIBXSTREAM_ASYNC+1)/2)
mutable _Offload_stream m_handle; // lazy creation
mutable size_t m_npartitions;
#endif
};
const libxstream_stream* cast_to_stream(const void* stream);
libxstream_stream* cast_to_stream(void* stream);
const libxstream_stream* cast_to_stream(const libxstream_stream* stream);
libxstream_stream* cast_to_stream(libxstream_stream* stream);
const libxstream_stream* cast_to_stream(const libxstream_stream& stream);
libxstream_stream* cast_to_stream(libxstream_stream& stream);
template<typename T> libxstream_stream* cast_to_stream(T stream) {
libxstream_use_sink(&stream);
LIBXSTREAM_ASSERT(0 == stream);
return static_cast<libxstream_stream*>(0);
}
#endif // defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
#endif // LIBXSTREAM_STREAM_HPP

View file

@ -205,7 +205,7 @@
#============================================================================
# qs types....what basic types are needed to do a qs calculation (but not e.g. fist)
#
#
#============================================================================
{'dirname':'qstypes',
'requires':["../base", "../common", "../mpiwrap", "../input", "../aobasis","../systemtypes", "../fm", "../dbcsr", "../pw", "../dbcsrwrap"],

View file

@ -88,7 +88,7 @@ def main():
if(pp.has_key('requires-')):
for i in pp['requires-']:
while i in packages[p]['requires']:
packages[p]['requires'].remove(i)
packages[p]['requires'].remove(i)
# process the manifests
for p in packages.keys():

0
tools/plot_mem_from_trace.py Normal file → Executable file
View file

0
tools/prettify/fprettify/__init__.py Normal file → Executable file
View file

View file

@ -121,7 +121,7 @@ case "$with_openblas" in
FC="${FC}" \
PREFIX="${pkg_install_dir}" \
install > install.omp.log 2>&1
fi
fi
cd ..
write_checksums "${install_lock_file}" "${SCRIPT_DIR}/$(basename ${SCRIPT_NAME})"
fi

View file

@ -645,7 +645,7 @@ download_pkg() {
return 1
fi
# checksum
checksum "$__filename" "$__sha256"
checksum "$__filename" "$__sha256"
}
# verify the checksums inside the given checksum file