Skip to content

Commit

Permalink
Modify it to the new interface DLTcollab#59
Browse files Browse the repository at this point in the history
  • Loading branch information
ajblane committed Aug 20, 2018
1 parent 6c98c16 commit 119e67d
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 99 deletions.
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,15 @@ ifeq ("$(BUILD_SSE)","1")
CFLAGS += -msse2 -DENABLE_SSE
endif
endif
endif

ifeq ("$(BUILD_GPU)","1")
include mk/opencl.mk
endif

ifeq ("$(BUILD_FPGA_ACCEL)","1")
CFLAGS += -DENABLE_FPGA_ACCEL
endif

ifeq ("$(BUILD_JNI)","1")
include mk/java.mk
endif
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![Build Status](https://travis-ci.org/DLTcollab/dcurl.svg?branch=dev)](https://travis-ci.org/DLTcollab/dcurl)
![Supported IRI version](https://img.shields.io/badge/Supported%20IRI%20Version-1.5.3-brightgreen.svg)

Hardware-accelerated implementation for IOTA PearlDiver, which utilizes multi-threaded SIMD and GPU.
Hardware-accelerated implementation for IOTA PearlDiver, which utilizes multi-threaded SIMD, FPGA and GPU.

# Introduction
dcurl exploits SIMD instructions on CPU and OpenCL on GPU. Both CPU and GPU accelerations can be
Expand Down
13 changes: 11 additions & 2 deletions src/dcurl.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@
#if defined(ENABLE_OPENCL)
#include "pow_cl.h"
#endif
#if defined(ENABLE_FPGA_ACCEL)
#include "pow_fpga_accel.h"
#endif
#include "trinary.h"
#include "implcontext.h"
#if defined(ENABLE_AVX)
#include "pow_avx.h"
#elif defined(ENABLE_SSE)
#include "pow_sse.h"
#elif defined(ENABLE_FPGA_ACCEL)
#include "pow_fpga_accel.h"
#else
#include "pow_c.h"
#endif
Expand Down Expand Up @@ -53,6 +54,10 @@ extern ImplContext PoWC_Context;
extern ImplContext PoWCL_Context;
#endif

#if defined(ENABLE_FPGA_ACCEL)
extern ImplContext PoWFPGAAccel_Context;
#endif

bool dcurl_init()
{
bool ret = true;
Expand All @@ -69,6 +74,10 @@ bool dcurl_init()
ret &= registerImplContext(&PoWCL_Context);
#endif

#if defined(ENABLE_FPGA_ACCEL)
ret &= registerImplContext(&PoWFPGAAccel_Context);
#endif

#ifdef __APPLE__
notify = dispatch_semaphore_create(0);
#else
Expand Down
239 changes: 151 additions & 88 deletions src/pow_fpga_accel.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include "constants.h"
#include "implcontext.h"
#include "trinary.h"

#define HPS_TO_FPGA_BASE 0xC0000000
Expand All @@ -33,137 +33,200 @@
S[3] = (I >> 24) & 0xff; \
}

static int ctrl_fd;
static int in_fd;
static int out_fd;
static int devmem_fd;
static void *fpga_regs_map;
static uint32_t *cpow_map;

int pow_fpga_accel_init()
static bool PoWFPGAAccel(void *pow_ctx)
{
ctrl_fd = 0;
in_fd = 0;
out_fd = 0;
devmem_fd = 0;
fpga_regs_map = 0;
cpow_map = 0;
PoW_FPGA_Accel_Context *ctx = (PoW_FPGA_Accel_Context *) pow_ctx;

ctrl_fd = open(DEV_CTRL_FPGA, O_RDWR);
int8_t fpga_out_nonce_trits[NonceTrinarySize];

if (ctrl_fd < 0) {
perror("cpow-ctrl open fail");
goto fail_dev_open_ctrl;
}
char result[4];
char buf[4];

in_fd = open(DEV_IDATA_FPGA, O_RDWR);
Trytes_t *object_trytes =
initTrytes(ctx->input_trytes, (transactionTrinarySize) / 3);
if (!object_trytes)
return false;

if (in_fd < 0) {
perror("cpow-idata open fail");
goto fail_dev_open_idata;
}
Trits_t *object_trits = trits_from_trytes(object_trytes);
if (!object_trits)
return false;

if (write(ctx->in_fd, (char *) object_trits->data, transactionTrinarySize) <
0)
return false;

INT2STRING(ctx->mwm, buf);
if (write(ctx->ctrl_fd, buf, sizeof(buf)) < 0)
return false;
if (read(ctx->ctrl_fd, result, sizeof(result)) < 0)
return false;

if (read(ctx->out_fd, (char *) fpga_out_nonce_trits, NonceTrinarySize) < 0)
return false;

Trits_t *object_nonce_trits =
initTrits(fpga_out_nonce_trits, NonceTrinarySize);
if (!object_nonce_trits)
return false;

Trytes_t *nonce_trytes = trytes_from_trits(object_nonce_trits);
if (!nonce_trytes)
return false;

out_fd = open(DEV_ODATA_FPGA, O_RDWR);
memcpy(ctx->output_trytes, ctx->input_trytes, (NonceTrinaryOffset) / 3);
memcpy(ctx->output_trytes + ((NonceTrinaryOffset) / 3), nonce_trytes->data,
((transactionTrinarySize) - (NonceTrinaryOffset)) / 3);

freeTrobject(object_trytes);
freeTrobject(object_trits);
freeTrobject(object_nonce_trits);
freeTrobject(nonce_trytes);

if (out_fd < 0) {
perror("cpow-odata open fail");
goto fail_dev_open_odata;
return true;
}

static bool PoWFPGAAccel_Context_Initialize(ImplContext *impl_ctx)
{
int i = 0;
devmem_fd = 0;
fpga_regs_map = 0;
cpow_map = 0;

PoW_FPGA_Accel_Context *ctx = (PoW_FPGA_Accel_Context *) malloc(
sizeof(PoW_FPGA_Accel_Context) * impl_ctx->num_max_thread);
if (!ctx)
goto fail_to_malloc;

for (i = 0; i < impl_ctx->num_max_thread; i++) {
ctx[i].ctrl_fd = open(DEV_CTRL_FPGA, O_RDWR);
if (ctx[i].ctrl_fd < 0) {
perror("cpow-ctrl open fail");
goto fail_to_open_ctrl;
}
ctx[i].in_fd = open(DEV_IDATA_FPGA, O_RDWR);
if (ctx[i].in_fd < 0) {
perror("cpow-idata open fail");
goto fail_to_open_idata;
}
ctx[i].out_fd = open(DEV_ODATA_FPGA, O_RDWR);
if (ctx[i].out_fd < 0) {
perror("cpow-odata open fail");
goto fail_to_open_odata;
}
impl_ctx->bitmap = impl_ctx->bitmap << 1 | 0x1;
}
impl_ctx->context = ctx;
pthread_mutex_init(&impl_ctx->lock, NULL);

devmem_fd = open("/dev/mem", O_RDWR | O_SYNC);

if (devmem_fd < 0) {
perror("devmem open");
goto fail_dev_open_mem_open;
goto fail_to_open_memopen;
}

fpga_regs_map =
(uint32_t *) mmap(NULL, HPS_TO_FPGA_SPAN, PROT_READ | PROT_WRITE,
MAP_SHARED, devmem_fd, HPS_TO_FPGA_BASE);
cpow_map = (uint32_t *) (fpga_regs_map + CPOW_BASE);

if (fpga_regs_map == MAP_FAILED) {
perror("devmem mmap");
goto fail_dev_open_mem_map;
goto fail_to_open_memmap;
}

return 1;
cpow_map = (uint32_t *) (fpga_regs_map + CPOW_BASE);

return true;

fail_to_open_memmap:
close(devmem_fd);
fail_to_open_memopen:
close(out_fd);
close(ctx[i].out_fd);
fail_to_open_odata:
close(in_fd);
close(ctx[i].in_fd);
fail_to_open_idata:
close(ctrl_fd);
close(ctx[i].ctrl_fd);
fail_to_open_ctrl:
return 0;
fail_to_malloc:
for (int j = i - 1; j > 0; j--) {
close(ctx[j].in_fd);
close(ctx[j].out_fd);
close(ctx[j].ctrl_fd);
}
return false;
}

void pow_fpga_accel_destroy()
static void PoWFPGAAccel_Context_Destroy(ImplContext *impl_ctx)
{
int result;

close(in_fd);
close(out_fd);
close(ctrl_fd);

result = munmap(fpga_regs_map, HPS_TO_FPGA_SPAN);

close(devmem_fd);
PoW_FPGA_Accel_Context *ctx = (PoW_FPGA_Accel_Context *) impl_ctx->context;
for (int i = 0; i < impl_ctx->num_max_thread; i++) {
close(ctx[i].in_fd);
close(ctx[i].out_fd);
close(ctx[i].ctrl_fd);
}
free(ctx);

int result = munmap(fpga_regs_map, HPS_TO_FPGA_SPAN);
if (result < 0) {
perror("devmem munmap");
}

close(devmem_fd);
}

int8_t *PowFPGAAccel(int8_t *itrytes, int mwm, int index)
static void *PoWFPGAAccel_getPoWContext(ImplContext *impl_ctx,
int8_t *trytes,
int mwm)
{
int8_t fpga_out_nonce_trits[NonceTrinarySize];
int8_t *otrytes =
(int8_t *) malloc(sizeof(int8_t) * (transactionTrinarySize) / 3);

char result[4];
char buf[4];

Trytes_t *object_trytes = initTrytes(itrytes, (transactionTrinarySize) / 3);
if (!object_trytes)
return NULL;

Trits_t *object_trits = trits_from_trytes(object_trytes);
if (!object_trits)
return NULL;

if (write(in_fd, (char *) object_trits->data, transactionTrinarySize) < 0)
return NULL;

INT2STRING(mwm, buf);
if (write(ctrl_fd, buf, sizeof(buf)) < 0)
return NULL;
if (read(ctrl_fd, result, sizeof(result)) < 0)
return NULL;
pthread_mutex_lock(&impl_ctx->lock);
for (int i = 0; i < impl_ctx->num_max_thread; i++) {
if (impl_ctx->bitmap & (0x1 << i)) {
impl_ctx->bitmap &= ~(0x1 << i);
pthread_mutex_unlock(&impl_ctx->lock);
PoW_FPGA_Accel_Context *ctx =
impl_ctx->context + sizeof(PoW_FPGA_Accel_Context) * i;
memcpy(ctx->input_trytes, trytes, (transactionTrinarySize) / 3);
ctx->mwm = mwm;
ctx->indexOfContext = i;
return ctx;
}
}

if (read(out_fd, (char *) fpga_out_nonce_trits, NonceTrinarySize) < 0)
return NULL;
pthread_mutex_unlock(&impl_ctx->lock);
return NULL; /* It should not happen */
}

Trits_t *object_nonce_trits =
initTrits(fpga_out_nonce_trits, NonceTrinarySize);
if (!object_nonce_trits)
return NULL;
static bool PoWFPGAAccel_freePoWContext(ImplContext *impl_ctx, void *pow_ctx)
{
pthread_mutex_lock(&impl_ctx->lock);
impl_ctx->bitmap |= 0x1
<< ((PoW_FPGA_Accel_Context *) pow_ctx)->indexOfContext;
pthread_mutex_unlock(&impl_ctx->lock);
return true;
}

Trytes_t *nonce_trytes = trytes_from_trits(object_nonce_trits);
if (!nonce_trytes)
static int8_t *PoWFPGAAccel_getPoWResult(void *pow_ctx)
{
int8_t *ret =
(int8_t *) malloc(sizeof(int8_t) * ((transactionTrinarySize) / 3));
if (!ret)
return NULL;

memcpy(otrytes, itrytes, (NonceTrinaryOffset) / 3);
memcpy(otrytes + ((NonceTrinaryOffset) / 3), nonce_trytes->data,
((transactionTrinarySize) - (NonceTrinaryOffset)) / 3);

freeTrobject(object_trytes);
freeTrobject(object_trits);
freeTrobject(object_nonce_trits);
freeTrobject(nonce_trytes);

return otrytes;
memcpy(ret, ((PoW_FPGA_Accel_Context *) pow_ctx)->output_trytes,
(transactionTrinarySize) / 3);
return ret;
}

ImplContext PoWFPGAAccel_Context = {
.context = NULL,
.bitmap = 0,
.num_max_thread = 1, // num_max_thread >= 1
.num_working_thread = 0,
.initialize = PoWFPGAAccel_Context_Initialize,
.destroy = PoWFPGAAccel_Context_Destroy,
.getPoWContext = PoWFPGAAccel_getPoWContext,
.freePoWContext = PoWFPGAAccel_freePoWContext,
.doThePoW = PoWFPGAAccel,
.getPoWResult = PoWFPGAAccel_getPoWResult,
};
18 changes: 15 additions & 3 deletions src/pow_fpga_accel.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,21 @@
#define POW_FPGA_ACCEL_H_

#include <stdint.h>
#include "constants.h"

int8_t *PowFPGAAccel(int8_t *itrytes, int mwm, int index);
int pow_fpga_accel_init();
void pow_fpga_accel_destroy();
typedef struct _pow_fpga_accel_context PoW_FPGA_Accel_Context;

struct _pow_fpga_accel_context {
/* Management of Multi-thread */
int indexOfContext;
/* Arguments of PoW */
int8_t input_trytes[(transactionTrinarySize) / 3]; /* 2673 */
int8_t output_trytes[(transactionTrinarySize) / 3]; /* 2673 */
int mwm;
/* Device files for the PFGA accelerator*/
int ctrl_fd;
int in_fd;
int out_fd;
};

#endif
Loading

0 comments on commit 119e67d

Please sign in to comment.