interface to cuda datalog package

This commit is contained in:
Vitor Santos Costa 2013-10-04 14:42:18 +01:00
parent 43163a190f
commit 74a6a79960
2 changed files with 144 additions and 31 deletions

View File

@ -1,15 +1,34 @@
// interface to CUDD Datalog evaluation // interface to CUDD Datalog evaluation
#include <stdio.h>
#include <stdlib.h>
#include "config.h" #include "config.h"
#include "YapInterface.h" #include "YapInterface.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct predicate_struct {
int name;
int num_rows;
int num_columns;
int is_fact;
int *address_host_table;
} predicate;
// initialize CUDA system
void Cuda_Initialize( void ); void Cuda_Initialize( void );
void *Cuda_NewFacts(int nrows, int ncols, int mat[]); // add/replace a set of facts for predicate pred
int Cuda_NewFacts(predicate *pred);
void *Cuda_NewRule(int nrows, int ncols, int vec[], int len); // add/replace a rule for predicate pred
int Cuda_NewRule(predicate *pred);
// erase predicate pred
int Cuda_Erase(predicate *pred);
// evaluate predicate pred, mat is bound to a vector of solutions, and
// output the count
int Cuda_Eval(predicate *pred, int **mat);
void init_cuda( void ); void init_cuda( void );
@ -27,42 +46,56 @@ dump_mat(int mat[], int nrows, int ncols)
} }
static void static void
dump_vec(int vec[], int sz) dump_vec(int vec[], int rows)
{ {
int i; int i = 1;
int j = 0;
printf("%d", vec[0]); printf("%d", vec[0]);
for ( i=1; i< sz; i++) { for (j = 0; j < rows; j++) {
printf(", %d", vec[i]); for ( ; vec[i]; i++ ) {
printf(", %d", vec[i]);
}
printf(", 0");
i++;
} }
printf("\n"); printf("\n");
} }
// stubs, for now. // stubs, will point at Carlos code.
void Cuda_Initialize( void ) void Cuda_Initialize( void )
{ {
} }
void *Cuda_NewFacts(int nrows, int ncols, int mat[]) int Cuda_NewFacts(predicate *pe)
{ {
dump_mat( mat, nrows, ncols ); dump_mat( pe->address_host_table, pe->num_rows, pe->num_columns );
return NULL; return TRUE;
} }
void *Cuda_NewRule(int nrows, int ncols, int vec[], int len) int Cuda_NewRule(predicate *pe)
{ {
dump_vec(vec, len); dump_vec( pe->address_host_table, pe->num_rows);
return NULL; return TRUE;
}
int Cuda_Erase(predicate *pe)
{
if (pe->address_host_table)
free( pe->address_host_table );
free( pe );
return TRUE;
} }
static int static int
p_load_facts( void ) { load_facts( void ) {
int nrows = YAP_IntOfTerm(YAP_ARG1); int nrows = YAP_IntOfTerm(YAP_ARG1);
int ncols = YAP_IntOfTerm(YAP_ARG2), i = 0; int ncols = YAP_IntOfTerm(YAP_ARG2), i = 0;
int *mat = (int *)malloc(sizeof(int)*nrows*ncols);
YAP_Term t3 = YAP_ARG3; YAP_Term t3 = YAP_ARG3;
void *cudaobj; int *mat = (int *)malloc(sizeof(int)*nrows*ncols);
int pname = YAP_AtomToInt(YAP_NameOfFunctor(YAP_FunctorOfTerm(YAP_HeadOfTerm(t3))));
predicate *pred;
while(YAP_IsPairTerm(t3)) { while(YAP_IsPairTerm(t3)) {
int j = 0; int j = 0;
@ -79,22 +112,39 @@ p_load_facts( void ) {
t3 = YAP_TailOfTerm( t3 ); t3 = YAP_TailOfTerm( t3 );
i++; i++;
} }
cudaobj = Cuda_NewFacts(nrows, ncols, mat); if (YAP_IsVarTerm( YAP_ARG4)) {
return YAP_Unify(YAP_ARG4, YAP_MkIntTerm((YAP_Int)cudaobj)); // 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;
}
} }
static int static int
p_load_rule( void ) { load_rule( void ) {
// maximum of 2K symbols per rule, should be enough for ILP // maximum of 2K symbols per rule, should be enough for ILP
int vec[2048], *ptr = vec; int vec[2048], *ptr = vec, *nvec;
// qK different variables; // qK different variables;
YAP_Term vars[1024]; YAP_Term vars[1024];
int nvars = 0; int nvars = 0;
int ngoals = YAP_IntOfTerm(YAP_ARG1); /* gives the number of goals */ int ngoals = YAP_IntOfTerm(YAP_ARG1); /* gives the number of goals */
int ncols = YAP_IntOfTerm(YAP_ARG2); int ncols = YAP_IntOfTerm(YAP_ARG2);
YAP_Term t3 = YAP_ARG3; YAP_Term t3 = YAP_ARG3;
void *cudaobj; int pname = YAP_AtomToInt(YAP_NameOfFunctor(YAP_FunctorOfTerm(YAP_HeadOfTerm(t3))));
predicate *pred;
while(YAP_IsPairTerm(t3)) { while(YAP_IsPairTerm(t3)) {
int j = 0; int j = 0;
@ -128,8 +178,65 @@ p_load_rule( void ) {
*ptr++ = 0; *ptr++ = 0;
t3 = YAP_TailOfTerm( t3 ); t3 = YAP_TailOfTerm( t3 );
} }
cudaobj = Cuda_NewRule(ngoals, ncols, vec, ptr-vec); if (YAP_IsVarTerm( YAP_ARG4)) {
return YAP_Unify(YAP_ARG4, YAP_MkIntTerm((YAP_Int)cudaobj)); // 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;
nvec = (int *)malloc(sizeof(int)*(ptr-vec));
memcpy(nvec, vec, sizeof(int)*(ptr-vec));
pred->address_host_table = nvec;
Cuda_NewRule( pred );
return YAP_Unify(YAP_ARG4, YAP_MkIntTerm((YAP_Int)pred));
}
static int
cuda_erase( void )
{
predicate *ptr = (predicate *)YAP_IntOfTerm(YAP_ARG1);
return Cuda_Erase( ptr );
}
static int
cuda_eval( void )
{
int *mat;
predicate *ptr = (predicate *)YAP_IntOfTerm(YAP_ARG1);
int n = Cuda_Eval( ptr, & mat);
int ncols = ptr->num_columns;
YAP_Term out = YAP_TermNil();
YAP_Functor f = YAP_MkFunctor(YAP_IntToAtom(ptr->name), ncols);
YAP_Term vec[256];
int i;
if (n < 0)
return FALSE;
for (i=0; i<n; i++) {
int ni = ((n-1)-i)*ncols, j;
for (j=0; j<ncols; j++) {
vec[i] = YAP_MkIntTerm(mat[ni+j]);
}
out = YAP_MkPairTerm(YAP_MkApplTerm( f, ncols, vec ), out);
}
return YAP_Unify(YAP_ARG2, out);
}
static int cuda_count( void )
{
int *mat;
predicate *ptr = (predicate *)YAP_IntOfTerm(YAP_ARG1);
int n = Cuda_Eval( ptr, & mat);
if (n < 0)
return FALSE;
return YAP_Unify(YAP_ARG2, YAP_MkIntTerm(n));
} }
static int first_time = TRUE; static int first_time = TRUE;
@ -140,7 +247,10 @@ init_cuda(void)
if (first_time) Cuda_Initialize(); if (first_time) Cuda_Initialize();
first_time = FALSE; first_time = FALSE;
YAP_UserCPredicate("load_facts", p_load_facts, 4); YAP_UserCPredicate("load_facts", load_facts, 4);
YAP_UserCPredicate("load_rule", p_load_rule, 4); YAP_UserCPredicate("load_rule", load_rule, 4);
YAP_UserCPredicate("cuda_erase", cuda_erase, 1);
YAP_UserCPredicate("cuda_eval", cuda_eval, 2);
YAP_UserCPredicate("cuda_count", cuda_count, 2);
} }

View File

@ -1,5 +1,8 @@
:- module(bdd, [cuda_extensional/2, :- module(bdd, [cuda_extensional/2,
cuda_rule/2]). cuda_rule/2,
cuda_erase/1,
cuda_eval/2,
cuda_count/2]).
tell_warning :- tell_warning :-
print_message(warning,functionality(cuda)). print_message(warning,functionality(cuda)).
@ -18,10 +21,10 @@ cuda_extensional( Call, IdFacts) :-
cuda_rule((Head :- Body) , IdRules) :- cuda_rule((Head :- Body) , IdRules) :-
body_to_list( Body, L, [], 1, N), body_to_list( Body, L, [], 1, N),
functor(Head, Na, Ar), functor(Head, Na, Ar),
load_rule( N, Arity, [Head|L], IdRules ). load_rule( N, Ar, [Head|L], IdRules ).
body_to_list( (B1, B2), LF, L0, N0, N) :- !, body_to_list( (B1, B2), LF, L0, N0, NF) :- !,
body_to_list( B1, LF, LI, N0, N1), body_to_list( B1, LF, LI, N0, N1),
body_to_list( B2, LI, L0, N1, NF). body_to_list( B2, LI, L0, N1, NF).
body_to_list( B, [B|L], L, N0, N) :- body_to_list( B, [B|L], L, N0, N) :-