This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/packages/cuda/cuda.c

602 lines
13 KiB
C
Raw Normal View History

2013-10-04 13:22:00 +01:00
// interface to CUDD Datalog evaluation
#include "config.h"
#include "YapInterface.h"
2013-10-04 14:42:18 +01:00
#include <stdio.h>
#include <stdlib.h>
2013-10-07 12:20:00 +01:00
#include <stdint.h>
2013-10-04 14:42:18 +01:00
#include <string.h>
2016-04-19 23:30:02 +01:00
#include <inttypes.h>
2013-10-07 12:20:00 +01:00
#include "pred.h"
2013-10-04 14:42:18 +01:00
2016-04-19 23:30:02 +01:00
#define MAXARG 100
2013-10-07 13:48:19 +01:00
YAP_Atom AtomEq,
AtomGt,
AtomLt,
AtomGe,
AtomLe,
2016-04-19 23:30:02 +01:00
AtomDf,
AtomNt;
2013-10-07 13:48:19 +01:00
2016-04-19 23:30:02 +01:00
predicate *facts[MAXARG]; /*Temporary solution to maintain facts and rules*/
predicate *rules[MAXARG];
2013-10-07 12:20:00 +01:00
int32_t cf = 0, cr = 0;
2013-10-04 13:22:00 +01:00
2016-04-19 23:30:02 +01:00
char names[1024];
2013-10-04 14:42:18 +01:00
// initialize CUDA system
2013-10-04 13:22:00 +01:00
void Cuda_Initialize( void );
2013-10-04 14:42:18 +01:00
// add/replace a set of facts for predicate pred
2013-10-07 12:20:00 +01:00
int32_t Cuda_NewFacts(predicate *pred);
2013-10-04 13:22:00 +01:00
2013-10-04 14:42:18 +01:00
// add/replace a rule for predicate pred
2013-10-07 12:20:00 +01:00
int32_t Cuda_NewRule(predicate *pred);
2013-10-04 14:42:18 +01:00
// erase predicate pred
2013-10-07 12:20:00 +01:00
int32_t Cuda_Erase(predicate *pred);
2013-10-04 14:42:18 +01:00
// evaluate predicate pred, mat is bound to a vector of solutions, and
// output the count
2013-10-07 12:20:00 +01:00
//int32_t Cuda_Eval(predicate *pred, int32_t **mat); This functions arguments were changed, please see pred.h
2013-10-04 13:22:00 +01:00
void init_cuda( void );
2013-10-16 14:52:54 +01:00
//#define DEBUG_INTERFACE 1
2016-04-19 23:30:02 +01:00
#ifdef ROCKIT
static int32_t query[100];
static int32_t qcont = 0;
static int cuda_init_query(void)
{
int32_t pname = YAP_AtomToInt(YAP_AtomOfTerm(YAP_ARG1));
query[qcont] = pname;
qcont++;
query[qcont] = 0;
return TRUE;
}
#endif
2013-10-07 12:38:08 +01:00
#if DEBUG_INTERFACE
2013-10-04 13:22:00 +01:00
static void
2013-10-07 12:20:00 +01:00
dump_mat(int32_t mat[], int32_t nrows, int32_t ncols)
2013-10-04 13:22:00 +01:00
{
2013-10-16 14:52:54 +01:00
return;
2013-10-07 12:20:00 +01:00
int32_t i, j;
2013-10-04 13:22:00 +01:00
for ( i=0; i< nrows; i++) {
printf("%d", mat[i*ncols]);
for (j=1; j < ncols; j++) {
printf(", %d", mat[i*ncols+j]);
}
printf("\n");
}
}
static void
2013-10-07 12:20:00 +01:00
dump_vec(int32_t vec[], int32_t rows)
2013-10-04 13:22:00 +01:00
{
2013-10-07 12:20:00 +01:00
int32_t i = 1;
int32_t j = 0;
2013-10-16 14:52:54 +01:00
2013-10-04 14:42:18 +01:00
for (j = 0; j < rows; j++) {
for ( ; vec[i]; i++ ) {
printf(", %d", vec[i]);
}
printf(", 0");
i++;
2013-10-04 13:22:00 +01:00
}
printf("\n");
}
2013-10-07 12:38:08 +01:00
#endif /* DEBUG_INTERFACE */
2013-10-04 13:22:00 +01:00
2013-10-04 14:42:18 +01:00
// stubs, will point at Carlos code.
2013-10-04 13:22:00 +01:00
void Cuda_Initialize( void )
{
}
2013-10-07 12:20:00 +01:00
int32_t Cuda_NewFacts(predicate *pe)
2013-10-04 13:22:00 +01:00
{
2013-10-07 12:38:08 +01:00
#if DEBUG_INTERFACE
2013-10-04 14:42:18 +01:00
dump_mat( pe->address_host_table, pe->num_rows, pe->num_columns );
2013-10-07 12:38:08 +01:00
#endif
2016-04-19 23:30:02 +01:00
#ifdef ROCKIT
if(cf >= 0)
{
facts[cf] = pe;
cf++;
}
#else
2013-10-07 12:20:00 +01:00
facts[cf] = pe;
cf++;
2016-04-19 23:30:02 +01:00
#endif
2013-10-04 14:42:18 +01:00
return TRUE;
2013-10-04 13:22:00 +01:00
}
2013-10-07 12:20:00 +01:00
int32_t Cuda_NewRule(predicate *pe)
2013-10-04 13:22:00 +01:00
{
2013-10-07 12:38:08 +01:00
#if DEBUG_INTERFACE
2013-10-04 14:42:18 +01:00
dump_vec( pe->address_host_table, pe->num_rows);
2013-10-07 12:38:08 +01:00
#endif
2013-10-07 12:20:00 +01:00
rules[cr] = pe;
cr++;
2013-10-04 14:42:18 +01:00
return TRUE;
}
2013-10-07 12:20:00 +01:00
int32_t Cuda_Erase(predicate *pe)
2013-10-04 14:42:18 +01:00
{
2013-10-07 18:34:29 +01:00
int i = 0;
while ( rules[i] != pe )
i++;
while (i < cr-1) {
rules[i] = rules[i+1];
i++;
}
rules[i] = NULL;
cr--;
2013-10-04 14:42:18 +01:00
if (pe->address_host_table)
free( pe->address_host_table );
free( pe );
return TRUE;
2013-10-04 13:22:00 +01:00
}
2016-04-19 23:30:02 +01:00
static int
2013-10-04 14:42:18 +01:00
load_facts( void ) {
2013-10-04 13:22:00 +01:00
2013-10-07 12:20:00 +01:00
int32_t nrows = YAP_IntOfTerm(YAP_ARG1);
int32_t ncols = YAP_IntOfTerm(YAP_ARG2), i = 0;
2013-10-04 13:22:00 +01:00
YAP_Term t3 = YAP_ARG3;
2013-10-07 12:20:00 +01:00
int32_t *mat = (int32_t *)malloc(sizeof(int32_t)*nrows*ncols);
int32_t pname = YAP_AtomToInt(YAP_NameOfFunctor(YAP_FunctorOfTerm(YAP_HeadOfTerm(t3))));
2013-10-04 14:42:18 +01:00
predicate *pred;
2013-10-04 13:22:00 +01:00
while(YAP_IsPairTerm(t3)) {
2013-10-07 12:20:00 +01:00
int32_t j = 0;
2013-10-04 13:22:00 +01:00
YAP_Term th = YAP_HeadOfTerm(t3);
for (j = 0; j < ncols; j++) {
YAP_Term ta = YAP_ArgOfTerm(j+1, th);
if (YAP_IsAtomTerm(ta)) {
mat[i*ncols+j] = YAP_AtomToInt(YAP_AtomOfTerm(ta));
} else {
mat[i*ncols+j] = YAP_IntOfTerm(ta);
}
}
t3 = YAP_TailOfTerm( t3 );
i++;
}
2013-10-04 14:42:18 +01:00
if (YAP_IsVarTerm( YAP_ARG4)) {
// new
pred = (predicate *)malloc(sizeof(predicate));
} else {
pred = (predicate *)YAP_IntOfTerm(YAP_ARG4);
if (pred->address_host_table)
free( pred->address_host_table );
}
pred->name = pname;
pred->num_rows = nrows;
pred->num_columns = ncols;
pred->is_fact = TRUE;
pred->address_host_table = mat;
Cuda_NewFacts(pred);
if (YAP_IsVarTerm( YAP_ARG4)) {
return YAP_Unify(YAP_ARG4, YAP_MkIntTerm((YAP_Int)pred));
} else {
return TRUE;
}
2013-10-04 13:22:00 +01:00
}
static int currentFact = 0;
static predicate *currentPred = NULL;
2016-04-19 23:30:02 +01:00
static int
cuda_init_facts( void ) {
int32_t nrows = YAP_IntOfTerm(YAP_ARG1);
2016-04-19 23:30:02 +01:00
int32_t ncols = YAP_IntOfTerm(YAP_ARG2);
int32_t *mat = (int32_t *)malloc(sizeof(int32_t)*nrows*ncols);
int32_t pname = YAP_AtomToInt(YAP_AtomOfTerm(YAP_ARG3));
predicate *pred;
2016-04-19 23:30:02 +01:00
strcat(names, YAP_AtomName(YAP_AtomOfTerm(YAP_ARG3)));
strcat(names, " ");
if (!mat)
return FALSE;
if (YAP_IsVarTerm( YAP_ARG4)) {
// new
pred = (predicate *)malloc(sizeof(predicate));
} else {
pred = (predicate *)YAP_IntOfTerm(YAP_ARG4);
if (pred->address_host_table)
free( pred->address_host_table );
}
pred->name = pname;
pred->num_rows = nrows;
pred->num_columns = ncols;
pred->is_fact = TRUE;
pred->address_host_table = mat;
currentPred = pred;
currentFact = 0;
if (YAP_IsVarTerm( YAP_ARG4)) {
return YAP_Unify(YAP_ARG4, YAP_MkIntTerm((YAP_Int)pred));
} else {
return TRUE;
}
}
2016-04-19 23:30:02 +01:00
static int
cuda_load_fact( void ) {
2016-04-19 23:30:02 +01:00
int i = currentFact;
#if defined(DATALOG) || defined(TUFFY)
YAP_Term th = YAP_ARG1;
int ncols = currentPred->num_columns;
2016-04-19 23:30:02 +01:00
int j;
int *mat = currentPred->address_host_table;
for (j = 0; j < ncols; j++) {
YAP_Term ta = YAP_ArgOfTerm(j+1, th);
if (YAP_IsAtomTerm(ta)) {
mat[i*ncols+j] = YAP_AtomToInt(YAP_AtomOfTerm(ta));
} else {
mat[i*ncols+j] = YAP_IntOfTerm(ta);
}
}
2016-04-19 23:30:02 +01:00
#endif
i++;
if (i == currentPred->num_rows) {
Cuda_NewFacts(currentPred);
currentPred = NULL;
currentFact = 0;
} else {
currentFact = i;
}
2013-11-04 21:41:26 +00:00
return TRUE;
}
2016-04-19 23:30:02 +01:00
static int
2013-10-04 14:42:18 +01:00
load_rule( void ) {
2013-10-04 13:22:00 +01:00
// maximum of 2K symbols per rule, should be enough for ILP
2016-04-19 23:30:02 +01:00
int32_t vec[2048], *ptr = vec, *nvec, neg[2048];
2013-10-04 13:22:00 +01:00
// qK different variables;
YAP_Term vars[1024];
2016-04-19 23:30:02 +01:00
int32_t nvars = 0, x;
2013-10-07 12:20:00 +01:00
int32_t ngoals = YAP_IntOfTerm(YAP_ARG1); /* gives the number of goals */
int32_t ncols = YAP_IntOfTerm(YAP_ARG2);
2013-10-04 13:22:00 +01:00
YAP_Term t3 = YAP_ARG3;
2016-04-19 23:30:02 +01:00
YAP_Atom name = YAP_NameOfFunctor(YAP_FunctorOfTerm(YAP_HeadOfTerm(t3)));
int32_t pname = YAP_AtomToInt(name);
const char *strname = YAP_AtomName(name);
2013-10-04 14:42:18 +01:00
predicate *pred;
2016-04-19 23:30:02 +01:00
int32_t cont = 0;
memset(neg, 0x0, 2048 * sizeof(int32_t));
2013-10-04 13:22:00 +01:00
while(YAP_IsPairTerm(t3)) {
2016-04-19 23:30:02 +01:00
int32_t j = 0, m;
2013-10-04 13:22:00 +01:00
YAP_Term th = YAP_HeadOfTerm(t3);
YAP_Functor f = YAP_FunctorOfTerm( th );
2013-10-07 12:20:00 +01:00
int32_t n = YAP_ArityOfFunctor( f );
2013-10-07 13:48:19 +01:00
YAP_Atom at = YAP_NameOfFunctor( f );
if (at == AtomEq)
*ptr++ = SBG_EQ;
else if (at == AtomGt)
*ptr++ = SBG_GT;
else if (at == AtomLt)
*ptr++ = SBG_LT;
else if (at == AtomGe)
*ptr++ = SBG_GE;
else if (at == AtomLe)
*ptr++ = SBG_LE;
else if (at == AtomDf)
*ptr++ = SBG_DF;
2016-04-19 23:30:02 +01:00
else if (at == AtomNt)
{
neg[cont] = 1;
cont++;
}
2013-10-07 13:48:19 +01:00
else
2016-04-19 23:30:02 +01:00
{
*ptr++ = YAP_AtomToInt( at );
cont++;
}
2013-10-04 13:22:00 +01:00
for (j = 0; j < n; j++) {
YAP_Term ta = YAP_ArgOfTerm(j+1, th);
if (YAP_IsVarTerm(ta)) {
2013-10-07 12:20:00 +01:00
int32_t k;
2013-10-04 13:22:00 +01:00
for (k = 0; k< nvars; k++) {
if (vars[k] == ta) {
*ptr++ = k+1;
break;
}
}
if (k == nvars) {
vars[k] = ta;
*ptr++ = k+1;
nvars++;
}
} else if (YAP_IsAtomTerm(ta)) {
*ptr++ = -YAP_AtomToInt(YAP_AtomOfTerm(ta));
2016-04-19 23:30:02 +01:00
} else if (YAP_IsApplTerm(ta)) {
f = YAP_FunctorOfTerm( ta );
at = YAP_NameOfFunctor( f );
m = YAP_ArityOfFunctor( f );
*ptr++ = YAP_AtomToInt( at );
for (x = 0; x < m; x++) {
YAP_Term ta2 = YAP_ArgOfTerm(x+1, ta);
if (YAP_IsVarTerm(ta2)) {
int32_t k;
for (k = 0; k < nvars; k++) {
if (vars[k] == ta2) {
*ptr++ = k+1;
break;
}
}
if (k == nvars) {
vars[k] = ta2;
*ptr++ = k+1;
nvars++;
}
} else if (YAP_IsAtomTerm(ta2)) {
*ptr++ = -YAP_AtomToInt(YAP_AtomOfTerm(ta));
} else {
*ptr++ = -YAP_IntOfTerm(ta);
}
}
2013-10-04 13:22:00 +01:00
} else {
*ptr++ = -YAP_IntOfTerm(ta);
}
}
*ptr++ = 0;
t3 = YAP_TailOfTerm( t3 );
}
2013-10-04 14:42:18 +01:00
if (YAP_IsVarTerm( YAP_ARG4)) {
// new
pred = (predicate *)malloc(sizeof(predicate));
} else {
pred = (predicate *)YAP_IntOfTerm(YAP_ARG4);
if (pred->address_host_table)
free( pred->address_host_table );
}
pred->name = pname;
pred->num_rows = ngoals;
pred->num_columns = ncols;
pred->is_fact = FALSE;
2016-04-19 23:30:02 +01:00
x = (strlen(strname) + 1) * sizeof(char);
pred->predname = (char *)malloc(x);
2018-06-30 14:33:32 +01:00
memmove(pred->predname, strname, x);
2013-10-07 12:20:00 +01:00
nvec = (int32_t *)malloc(sizeof(int32_t)*(ptr-vec));
2018-06-30 14:33:32 +01:00
memmove(nvec, vec, sizeof(int32_t)*(ptr-vec));
2013-10-04 14:42:18 +01:00
pred->address_host_table = nvec;
2016-04-19 23:30:02 +01:00
pred->negatives = (int32_t *)malloc(sizeof(int32_t) * cont);
2018-06-30 14:33:32 +01:00
memmove(pred->negatives, neg, sizeof(int32_t) * cont);
2013-10-04 14:42:18 +01:00
Cuda_NewRule( pred );
return YAP_Unify(YAP_ARG4, YAP_MkIntTerm((YAP_Int)pred));
}
2016-04-19 23:30:02 +01:00
static int
2013-10-04 14:42:18 +01:00
cuda_erase( void )
{
predicate *ptr = (predicate *)YAP_IntOfTerm(YAP_ARG1);
return Cuda_Erase( ptr );
}
2016-04-19 23:30:02 +01:00
void setQuery(YAP_Term t1, int32_t **res)
{
int32_t *query = (int32_t *)malloc(MAXARG * sizeof(int32_t));
int32_t x, y = 0, *itr;
predicate *ptr = NULL;
if(YAP_IsPairTerm(t1))
{
while(YAP_IsPairTerm(t1))
{
ptr = (predicate *)YAP_IntOfTerm(YAP_HeadOfTerm(t1));
query[y] = ptr->name;
itr = ptr->address_host_table;
x = 2;
while(itr[x] != 0)
x++;
query[y+1] = itr[x+1];
t1 = YAP_TailOfTerm(t1);
y+=2;
}
}
else
{
ptr = (predicate *)YAP_IntOfTerm(t1);
query[y] = ptr->name;
itr = ptr->address_host_table;
x = 2;
while(itr[x] != 0)
x++;
query[y+1] = itr[x+1];
y += 2;
}
query[y] = -1;
query[y+1] = -1;
*res = query;
}
static int
2013-10-04 14:42:18 +01:00
cuda_eval( void )
{
2013-10-07 12:20:00 +01:00
int32_t *mat;
2016-04-19 23:30:02 +01:00
#if defined(DATALOG) || defined(TUFFY)
int32_t *query = NULL;
setQuery(YAP_ARG1, &query);
#endif
int32_t finalDR = YAP_IntOfTerm(YAP_ARG3);
int32_t n = Cuda_Eval(facts, cf, rules, cr, query, & mat, names, finalDR);
#ifdef TUFFY
cf = 0;
#endif
#ifdef ROCKIT
if(cf > 0)
cf *= -1;
#endif
#if defined(TUFFY) || defined(ROCKIT)
cr = 0;
names[0] = '\0';
return FALSE;
#else
int32_t i;
2013-10-04 14:42:18 +01:00
predicate *ptr = (predicate *)YAP_IntOfTerm(YAP_ARG1);
2013-10-07 12:20:00 +01:00
int32_t ncols = ptr->num_columns;
2013-10-04 14:42:18 +01:00
YAP_Term out = YAP_TermNil();
YAP_Functor f = YAP_MkFunctor(YAP_IntToAtom(ptr->name), ncols);
YAP_Term vec[256];
2016-04-19 23:30:02 +01:00
YAP_Atom at;
2013-10-04 14:42:18 +01:00
if (n < 0)
return FALSE;
for (i=0; i<n; i++) {
2013-10-07 12:20:00 +01:00
int32_t ni = ((n-1)-i)*ncols, j;
2016-04-19 23:30:02 +01:00
printf("%s(", YAP_AtomName(YAP_IntToAtom(ptr->name)));
2013-10-04 14:42:18 +01:00
for (j=0; j<ncols; j++) {
2013-10-07 12:38:08 +01:00
vec[j] = YAP_MkIntTerm(mat[ni+j]);
2016-04-19 23:30:02 +01:00
at = YAP_IntToAtom(mat[ni+j]);
if(at != NULL)
printf("%s", YAP_AtomName(at));
else
printf("%d", mat[ni+j]);
if(j < (ncols - 1))
printf(",");
2013-10-04 14:42:18 +01:00
}
out = YAP_MkPairTerm(YAP_MkApplTerm( f, ncols, vec ), out);
2016-04-19 23:30:02 +01:00
printf(")\n");
2013-10-04 14:42:18 +01:00
}
if (n > 0)
free( mat );
2013-10-04 14:42:18 +01:00
return YAP_Unify(YAP_ARG2, out);
2016-04-19 23:30:02 +01:00
#endif
2013-10-04 14:42:18 +01:00
}
2016-04-19 23:30:02 +01:00
static int
2013-10-09 11:23:45 +01:00
cuda_coverage( void )
{
int32_t *mat;
2016-04-19 23:30:02 +01:00
#if defined(DATALOG) || defined(TUFFY)
int32_t *query = NULL;
setQuery(YAP_ARG1, &query);
#endif
int32_t n = Cuda_Eval(facts, cf, rules, cr, query, & mat, 0, 0);
2013-10-09 11:23:45 +01:00
int32_t post = YAP_AtomToInt(YAP_AtomOfTerm(YAP_ARG2));
int32_t i = n/2, min = 0, max = n-1;
int32_t t0, t1;
2013-10-09 11:23:45 +01:00
if (n < 0)
return FALSE;
if (n == 0) {
return YAP_Unify(YAP_ARG4, YAP_MkIntTerm(0)) &&
YAP_Unify(YAP_ARG3, YAP_MkIntTerm(0));
}
t0 = mat[0], t1 = mat[(n-1)*2];
2013-10-09 11:23:45 +01:00
if (t0 == t1) { /* all sametype */
free( mat );
/* all pos */
if (t0 == post)
return YAP_Unify(YAP_ARG3, YAP_MkIntTerm(n)) &&
YAP_Unify(YAP_ARG4, YAP_MkIntTerm(0));
/* all neg */
return YAP_Unify(YAP_ARG4, YAP_MkIntTerm(n)) &&
YAP_Unify(YAP_ARG3, YAP_MkIntTerm(0));
}
do {
i = (min+max)/2;
if (i == min) i++;
if (mat[i*2] == t0) {
min = i;
} else {
max = i;
}
if (min+1 == max) {
free( mat );
if (t0 == post)
return YAP_Unify(YAP_ARG3, YAP_MkIntTerm(max)) &&
YAP_Unify(YAP_ARG4, YAP_MkIntTerm(n-max));
/* all neg */
return YAP_Unify(YAP_ARG4, YAP_MkIntTerm(max)) &&
YAP_Unify(YAP_ARG3, YAP_MkIntTerm(n-max));
}
} while ( TRUE );
}
2016-04-19 23:30:02 +01:00
static int cuda_count( void )
2013-10-04 14:42:18 +01:00
{
2013-10-07 12:20:00 +01:00
int32_t *mat;
2016-04-19 23:30:02 +01:00
#if defined(DATALOG) || defined(TUFFY)
int32_t *query = NULL;
setQuery(YAP_ARG1, &query);
#endif
int32_t n = Cuda_Eval(facts, cf, rules, cr, query, & mat, 0, 0);
2013-10-04 14:42:18 +01:00
if (n < 0)
return FALSE;
free( mat );
2013-10-04 14:42:18 +01:00
return YAP_Unify(YAP_ARG2, YAP_MkIntTerm(n));
2013-10-04 13:22:00 +01:00
}
2016-04-19 23:30:02 +01:00
static int cuda_statistics( void )
2013-10-16 16:19:03 +01:00
{
Cuda_Statistics();
return TRUE;
}
2013-10-04 13:22:00 +01:00
static int first_time = TRUE;
void
init_cuda(void)
{
if (first_time) Cuda_Initialize();
first_time = FALSE;
2013-10-07 13:48:19 +01:00
AtomEq = YAP_LookupAtom("=");
AtomGt = YAP_LookupAtom(">");
AtomLt = YAP_LookupAtom("<");
AtomGe = YAP_LookupAtom(">=");
AtomLe = YAP_LookupAtom("=<");
AtomDf = YAP_LookupAtom("\\=");
2016-04-19 23:30:02 +01:00
AtomNt = YAP_LookupAtom("not");
2013-10-04 14:42:18 +01:00
YAP_UserCPredicate("load_facts", load_facts, 4);
YAP_UserCPredicate("cuda_init_facts", cuda_init_facts, 4);
YAP_UserCPredicate("cuda_load_fact", cuda_load_fact, 1);
2013-10-04 14:42:18 +01:00
YAP_UserCPredicate("load_rule", load_rule, 4);
YAP_UserCPredicate("cuda_erase", cuda_erase, 1);
2016-04-19 23:30:02 +01:00
YAP_UserCPredicate("cuda_eval", cuda_eval, 3);
2013-10-09 11:23:45 +01:00
YAP_UserCPredicate("cuda_coverage", cuda_coverage, 4);
2013-10-04 14:42:18 +01:00
YAP_UserCPredicate("cuda_count", cuda_count, 2);
2013-10-16 16:19:03 +01:00
YAP_UserCPredicate("cuda_statistics", cuda_statistics, 0);
2016-04-19 23:30:02 +01:00
#ifdef ROCKIT
YAP_UserCPredicate("cuda_init_query", cuda_init_query, 1);
#endif
2013-10-04 13:22:00 +01:00
}