blob: fbb7d21e7e2d8877c6cec40da0c32b70b997ab72 [file] [log] [blame]
/* AUTORIGHTS
Copyright (C) 2007 Princeton University
This file is part of Ferret Toolkit.
Ferret Toolkit is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <stdio.h>
#include <math.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <cass.h>
#include <cass_stat.h>
#include <cass_timer.h>
#include <../image/image.h>
#ifdef ENABLE_PARSEC_HOOKS
#include <hooks.h>
#endif
#define MAXR 100
#define IMAGE_DIM 14
const char *db_dir = NULL;
const char *table_name = NULL;
const char *query_dir = NULL;
const char *output_path = NULL;
FILE *fout;
int top_K = 10;
char *extra_params = "-L 8 - T 20";
int input_end;
pthread_cond_t done;
pthread_mutex_t done_mutex;
cass_env_t *env;
cass_table_t *table;
cass_table_t *query_table;
int vec_dist_id = 0;
int vecset_dist_id = 0;
int NTHREAD = 1;
int DEPTH = 1;
/* ------- The Helper Functions ------- */
char path[BUFSIZ];
void do_query (const char *);
int scan_dir (const char *, char *head);
int dir_helper (char *dir, char *head)
{
DIR *pd = NULL;
struct dirent *ent = NULL;
int result = 0;
pd = opendir(dir);
if (pd == NULL) goto except;
for (;;)
{
ent = readdir(pd);
if (ent == NULL) break;
if (scan_dir(ent->d_name, head) != 0) return -1;
}
goto final;
except:
result = -1;
perror("Error:");
final:
if (pd != NULL) closedir(pd);
return result;
}
int scan_dir (const char *dir, char *head)
{
struct stat st;
int ret;
/* test for . and .. */
if (dir[0] == '.')
{
if (dir[1] == 0) return 0;
else if (dir[1] == '.')
{
if (dir[2] == 0) return 0;
}
}
/* append the name to the path */
strcat(head, dir);
ret = stat(path, &st);
if (ret != 0)
{
perror("Error:");
return -1;
}
if (S_ISREG(st.st_mode)) do_query(path);
else if (S_ISDIR(st.st_mode))
{
strcat(head, "/");
dir_helper(path, head + strlen(head));
}
/* removed the appended part */
head[0] = 0;
return 0;
}
/* ------ The Stages ------ */
void scan (void)
{
const char *dir = query_dir;
path[0] = 0;
if (strcmp(dir, ".") == 0)
{
dir_helper(".", path);
}
else
{
scan_dir(dir, path);
}
}
void do_query (const char *name)
{
cass_dataset_t ds;
cass_query_t query;
cass_result_t result;
cass_result_t *candidate;
{
unsigned char *HSV, *RGB;
unsigned char *mask;
int width, height, nrgn;
int r;
r = image_read_rgb_hsv(name, &width, &height, &RGB, &HSV);
assert(r == 0);
image_segment(&mask, &nrgn, RGB, width, height);
image_extract_helper(HSV, mask, width, height, nrgn, &ds);
/* free image & map */
free(HSV);
free(RGB);
free(mask);
}
memset(&query, 0, sizeof query);
query.flags = CASS_RESULT_LISTS | CASS_RESULT_USERMEM;
query.dataset = &ds;
query.vecset_id = 0;
query.vec_dist_id = vec_dist_id;
query.vecset_dist_id = vecset_dist_id;
query.topk = 2*top_K;
query.extra_params = extra_params;
cass_result_alloc_list(&result, ds.vecset[0].num_regions, query.topk);
cass_table_query(table, &query, &result);
memset(&query, 0, sizeof query);
query.flags = CASS_RESULT_LIST | CASS_RESULT_USERMEM | CASS_RESULT_SORT;
query.dataset = &ds;
query.vecset_id = 0;
query.vec_dist_id = vec_dist_id;
query.vecset_dist_id = vecset_dist_id;
query.topk = top_K;
query.extra_params = NULL;
candidate = cass_result_merge_lists(&result, (cass_dataset_t *)query_table->__private, 0);
query.candidate = candidate;
cass_result_free(&result);
cass_result_alloc_list(&result, 0, top_K);
cass_table_query(query_table, &query, &result);
cass_result_free(candidate);
free(candidate);
cass_dataset_release(&ds);
fprintf(fout, "%s", name);
ARRAY_BEGIN_FOREACH(result.u.list, cass_list_entry_t p)
{
char *obj = NULL;
if (p.dist == HUGE_VAL) continue;
cass_map_id_to_dataobj(query_table->map, p.id, &obj);
assert(obj != NULL);
fprintf(fout, "\t%s:%g", obj, p.dist);
} ARRAY_END_FOREACH;
fprintf(fout, "\n");
cass_result_free(&result);
}
int main (int argc, char *argv[])
{
stimer_t tmr;
int ret, i;
#ifdef PARSEC_VERSION
#define __PARSEC_STRING(x) #x
#define __PARSEC_XSTRING(x) __PARSEC_STRING(x)
printf("PARSEC Benchmark Suite Version "__PARSEC_XSTRING(PARSEC_VERSION)"\n");
fflush(NULL);
#else
printf("PARSEC Benchmark Suite\n");
fflush(NULL);
#endif //PARSEC_VERSION
#ifdef ENABLE_PARSEC_HOOKS
__parsec_bench_begin(__parsec_ferret);
#endif
if (argc < 8)
{
printf("%s <database> <table> <query dir> <top K> <depth> <n> <out>\n", argv[0]);
return 0;
}
db_dir = argv[1];
table_name = argv[2];
query_dir = argv[3];
top_K = atoi(argv[4]);
DEPTH = atoi(argv[5]);
NTHREAD = atoi(argv[6]);
if(NTHREAD != 1) {
printf("n must be 1 (serial version)\n");
exit(1);
}
output_path = argv[7];
fout = fopen(output_path, "w");
assert(fout != NULL);
cass_init();
ret = cass_env_open(&env, db_dir, 0);
if (ret != 0) { printf("ERROR: %s\n", cass_strerror(ret)); return 0; }
vec_dist_id = cass_reg_lookup(&env->vec_dist, "L2_float");
assert(vec_dist_id >= 0);
vecset_dist_id = cass_reg_lookup(&env->vecset_dist, "emd");
assert(vecset_dist_id >= 0);
i = cass_reg_lookup(&env->table, table_name);
table = query_table = cass_reg_get(&env->table, i);
i = table->parent_id;
if (i >= 0)
{
query_table = cass_reg_get(&env->table, i);
}
if (query_table != table) cass_table_load(query_table);
cass_map_load(query_table->map);
cass_table_load(table);
image_init(argv[0]);
stimer_tick(&tmr);
#ifdef ENABLE_PARSEC_HOOKS
__parsec_roi_begins();
#endif
scan();
#ifdef ENABLE_PARSEC_HOOKS
__parsec_roi_ends();
#endif
stimer_tuck(&tmr, "QUERY TIME");
ret = cass_env_close(env, 0);
if (ret != 0) { printf("ERROR: %s\n", cass_strerror(ret)); return 0; }
cass_cleanup();
image_cleanup();
fclose(fout);
#ifdef ENABLE_PARSEC_HOOKS
__parsec_bench_end();
#endif
return 0;
}