Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
2af1d7d
Start working on the numeric library
38 Apr 3, 2018
4c2fee6
Merge branch 'master' into numeric-support
38 Apr 4, 2018
31b0f63
Use the new representation for the matrix && complete the memory object
38 Apr 4, 2018
ccfc5cf
Add the utils for dimension data
38 Apr 4, 2018
6e749de
Start working on the field implemnetation
38 Apr 20, 2018
a6fd1ef
Add most of the code for the CPU field
38 Apr 20, 2018
647c9d2
Rename the types
38 Apr 20, 2018
72eaf4d
Add RLS callbacks to the cpu field type
38 Apr 22, 2018
7734a8d
Add header file for CPU continuation
38 Apr 22, 2018
126b906
Add the continuation for CPU field implementation
38 Apr 24, 2018
9b56dd4
Finish the field continuation token
38 Apr 24, 2018
d46ec7d
Change install directory from pnum to psnl
38 Apr 25, 2018
c381620
Start working on the field parser, which parse/load a field into memory
38 Apr 25, 2018
356035e
Add servlet options header
38 Apr 28, 2018
4fd51bd
Start working on the option parser implementation
38 May 2, 2018
bbffe9b
Add code for the option parser
38 May 3, 2018
908846e
Fix clang compile error
38 May 4, 2018
ab55a6a
Add code for the parser servlet
38 May 15, 2018
f5df40e
Fix the bug
38 May 15, 2018
0bd258b
Add a servlet so that we can dump the field result to raw pipe
38 May 15, 2018
1dadffe
Add code to initialize the field dumpping servlet
38 May 17, 2018
6a9223a
Make code compile with clang
38 May 17, 2018
2358afa
Add exec code for the field dumper
38 May 17, 2018
d5a2287
Tested the parser and dump seems working
38 May 23, 2018
b6301d2
Reviewing the PSNL code
38 May 24, 2018
68e6f03
Merge branch 'master' into numeric-support
38 May 24, 2018
88a0d4f
Add test case for the field parser and dump
38 May 25, 2018
1e3aae5
Fix the clang sanitizer error
38 May 25, 2018
86f846b
Fix the ODR violation
38 May 25, 2018
8b2103f
Review current code
38 May 26, 2018
3d86efb
Start working on the infrastructure for binary operations
38 May 26, 2018
dd55671
Working on the binary operator, TODO create cont for binary operator
38 May 26, 2018
5fd75b2
Merge branch 'master' into numeric-support
38 May 29, 2018
793c5e0
Use the continuation and ref counter from the pstd
38 May 29, 2018
8ddf0a1
Add the universal representation for the expression
38 May 30, 2018
3d74936
Still working on the expression representation
38 Jun 11, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions build/setup.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ else(APPLE)
set(SYSNAME ${CMAKE_SYSTEM_NAME})
endif(APPLE)

message(${CMAKE_CURRENT_BINARY_DIR})
message("Current binary directory: ${CMAKE_CURRENT_BINARY_DIR}")


file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin/lib)
Expand All @@ -29,7 +29,7 @@ set(LIB_DIR "lib")
# log level can be 0 to 6, 0 means no log, 6 means the most detialed log
if("$ENV{L}" STREQUAL "")
if("${LOG}" STREQUAL "")
set(LOG 4)
set(LOG 3)
endif("${LOG}" STREQUAL "")
else("$ENV{L}" STREQUAL "")
set(LOG $ENV{L})
Expand Down
4 changes: 3 additions & 1 deletion lib/pservlet/include/pservlet.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ extern "C" {
/**@brief the metadata defined in the plugin */
extern servlet_def_t RUNTIME_SERVLET_DEFINE_SYM;

#define SERVLET_DEF servlet_def_t RUNTIME_SERVLET_DEFINE_SYM
#define SERVLET_DEF \
const address_table_t* RUNTIME_ADDRESS_TABLE_SYM __attribute__((used)) = NULL; \
servlet_def_t RUNTIME_SERVLET_DEFINE_SYM

# ifdef __cplusplus
};
Expand Down
1 change: 0 additions & 1 deletion lib/pservlet/pservlet.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@

#include <pservlet.h>

const address_table_t* RUNTIME_ADDRESS_TABLE_SYM __attribute__((used)) = NULL;
8 changes: 8 additions & 0 deletions lib/psnl/build.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
set(TYPE shared-library)
set(LOCAL_CFLAGS "-fPIC")
set(LOCAL_LIBS pstd)
set(INSTALL "yes")
set(PACKAGE_CONF_INSTALL_PATH "include/psnl")
list(APPEND LOCAL_SOURCE cpu)
install_includes("${SOURCE_PATH}/include" "include/psnl" "*.h")
install_plumber_headers("include/psnl")
283 changes: 283 additions & 0 deletions lib/psnl/cpu/field.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
/**
* Copyright (C) 2018, Hao Hou
**/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>

#include <pservlet.h>
#include <pstd.h>

#include <psnl/dim.h>
#include <psnl/cpu/field.h>

/**
* @brief The actual data structure used for the Field lives on the CPU
**/
struct _psnl_cpu_field_t {
size_t elem_size; /*!< The element size */
pstd_scope_gc_obj_t* gc_obj; /*!< The GC object for this field */
uintpad_t __padding__[0];
psnl_dim_t dim[0]; /*!< The dimensional data */
char data[0]; /*!< The actual data section */
};
STATIC_ASSERTION_SIZE(psnl_cpu_field_t, dim, 0);
STATIC_ASSERTION_SIZE(psnl_cpu_field_t, data, 0);
STATIC_ASSERTION_LAST(psnl_cpu_field_t, dim);
STATIC_ASSERTION_LAST(psnl_cpu_field_t, data);

/**
* @brief Reperesent the string representation of a field
* @todo Do we need make the stream able to output seralized field?
**/
typedef struct {
const void* data; /*!< The actual data to be written */
size_t size; /*!< The size of the struct */
} _stream_t;

/**
* @brief Get the padded size from the original one
* @param size The size of the padded size
* @return the padded size
**/
static inline size_t _get_padded_size(size_t size)
{
size_t rem = size % sizeof(uintpad_t);

return rem > 0 ? size - rem + sizeof(uintpad_t) : size;
}

static int _field_data_free(void* obj)
{
/* TODO(field memory pool): cache the memory we are using at this point would be really helpful */
free(obj);
return 0;
}

psnl_cpu_field_t* psnl_cpu_field_new(const psnl_dim_t* dim, size_t elem_size)
{
if(NULL == dim || elem_size == 0)
ERROR_PTR_RETURN_LOG("Invalid arguments");

size_t size = sizeof(psnl_cpu_field_t) + psnl_dim_space_size(dim) * elem_size + _get_padded_size(psnl_dim_data_size(dim));

/* TODO(field memory pool): even though we just allocated from OS at this time, it should be better if we can cache the meomry we are using here */
psnl_cpu_field_t* ret = (psnl_cpu_field_t*)malloc(size);

if(NULL == ret)
ERROR_PTR_RETURN_LOG_ERRNO("Cannot allocate memory for the new CPU field");

memcpy(ret->dim, dim, psnl_dim_data_size(dim));
ret->elem_size = elem_size;
ret->gc_obj = NULL;

return ret;
}


int psnl_cpu_field_free(psnl_cpu_field_t* field)
{
if(NULL == field)
ERROR_RETURN_LOG(int, "Invalid arguments");

if(field->gc_obj != NULL)
ERROR_RETURN_LOG(int, "Refuse to dispose a committed RLS object");

return _field_data_free(field);
}

int psnl_cpu_field_incref(const psnl_cpu_field_t* field)
{
return pstd_scope_gc_incref(field->gc_obj);
}

int psnl_cpu_field_decref(const psnl_cpu_field_t* field)
{
return pstd_scope_gc_decref(field->gc_obj);
}

static void* _open(const void* mem)
{
_stream_t* ret = pstd_mempool_alloc(sizeof(_stream_t));

if(NULL == ret)
ERROR_PTR_RETURN_LOG("Cannot allocate memory for the stream object");

const psnl_cpu_field_t* data = (const psnl_cpu_field_t*)mem;

ret->size = _get_padded_size(psnl_dim_data_size(data->dim)) + psnl_dim_data_size(data->dim) * data->elem_size;

ret->data = mem;

return ret;
}

static int _close(void* stream_mem)
{
return pstd_mempool_free(stream_mem);
}

static int _eos(const void* stream_mem)
{
const _stream_t* stream = (const _stream_t*)stream_mem;

return stream->size > 0;
}

static size_t _read(void* __restrict stream_mem, void* __restrict buf, size_t count)
{
_stream_t* stream = (_stream_t*)stream_mem;

size_t ret = count;
if(ret > stream->size) ret = stream->size;

memcpy(buf, stream->data, ret);

stream->size -= ret;
stream->data = (const void*)(((const uint8_t*)stream->data) + ret);
return ret;
}

scope_token_t psnl_cpu_field_commit(psnl_cpu_field_t* field)
{
if(NULL == field)
ERROR_RETURN_LOG(scope_token_t, "Invalid arguments");

if(field->gc_obj != NULL)
ERROR_RETURN_LOG(scope_token_t, "Cannot re-committed a token that is already in RLS");

scope_entity_t ent = {
.data = field,
.free_func = _field_data_free,
.open_func = _open,
.close_func = _close,
.eos_func = _eos,
.read_func = _read
};

return pstd_scope_gc_add(&ent, &field->gc_obj);
}

void* psnl_cpu_field_get_data(psnl_cpu_field_t* field, psnl_dim_t const ** dim_buf)
{
if(NULL == field)
ERROR_PTR_RETURN_LOG("Invalid arguments");

if(NULL != dim_buf)
*dim_buf = field->dim;

return field->data + _get_padded_size(psnl_dim_data_size(field->dim));
}

const void* psnl_cpu_field_get_data_const(const psnl_cpu_field_t* field, psnl_dim_t const** dim_buf)
{
if(NULL == field)
ERROR_PTR_RETURN_LOG("Invalid arguments");

if(NULL != dim_buf)
*dim_buf = field->dim;

return field->data + _get_padded_size(psnl_dim_data_size(field->dim));
}

const psnl_cpu_field_t* psnl_cpu_field_from_rls(scope_token_t token)
{
if(ERROR_CODE(scope_token_t) == token)
ERROR_PTR_RETURN_LOG("Invlaid arguments");

pstd_scope_gc_obj_t* gc_obj = pstd_scope_gc_get(token);

return gc_obj == NULL ? NULL : gc_obj->obj;
}

/**
* @brief The map from the cell type to the field type
**/
static const char* _type_map[] = {
[PSNL_CPU_FIELD_CELL_TYPE_DOUBLE] = "plumber/std/numeric/DoubleField"
};
STATIC_ASSERTION_EQ(PSNL_CPU_FIELD_CELL_TYPE_COUNT, sizeof(_type_map) / sizeof(_type_map[0]));

int psnl_cpu_field_type_parse(const char* type_name, psnl_cpu_field_type_info_t* buf)
{
if(NULL == type_name || NULL == buf)
ERROR_RETURN_LOG(int, "Invalid arguments");

const char* major_begin = type_name;
const char* major_end = type_name;

for(;*major_end != 0 && *major_end != ' ' && *major_end != '\t'; major_end ++);

uint32_t type_code;
for(type_code = 0; _type_map[type_code] &&
!(major_begin + strlen(_type_map[type_code]) == major_end &&
0 == memcmp(major_begin, _type_map[type_code], (size_t)(major_end - major_begin)));
type_code ++);

if(_type_map[type_code] == NULL)
ERROR_RETURN_LOG(int, "Unknown field type: %s", type_name);

buf->cell_type = (psnl_cpu_field_cell_type_t)type_code;

switch(buf->cell_type)
{
case PSNL_CPU_FIELD_CELL_TYPE_DOUBLE:
buf->cell_size = sizeof(double);
break;

default:
ERROR_RETURN_LOG(int, "Unknown type code");
}

/* Then we need to parse the dimension */

const char* dim_start = major_end;

buf->n_dim = 0;

for(;*dim_start != 0 && (*dim_start == ' ' || *dim_start == '\t'); dim_start ++);

if(*dim_start != 0 && memcmp(dim_start, "@dim(", 5) == 0)
{
char* next = NULL;

long long dim_val = strtoll(dim_start + 5, &next, 0);

if(NULL == next || *next != ')')
ERROR_RETURN_LOG(int, "Invalid dimension description");

if(dim_val <= 0 || dim_val > 0xffffffffll)
ERROR_RETURN_LOG(int, "Invalid dimension value");

buf->n_dim = (uint32_t)dim_val;
}

return 0;
}

int psnl_cpu_field_type_dump(const psnl_cpu_field_type_info_t* info, char* buf, size_t buf_size)
{
if(NULL == info || NULL == buf)
ERROR_RETURN_LOG(int, "Invalid arguments");

#ifndef __clang__
if(info->cell_type < 0 || info->cell_type >= PSNL_CPU_FIELD_CELL_TYPE_COUNT)
#else
if(info->cell_type >= PSNL_CPU_FIELD_CELL_TYPE_COUNT)
#endif
ERROR_RETURN_LOG(int, "Invalid arguments: cell type code");

size_t bytes_needed = 0;

if(info->n_dim > 0)
bytes_needed = (size_t)snprintf(buf, buf_size, "%s @dim(%u)", _type_map[info->cell_type], info->n_dim);
else
bytes_needed = (size_t)snprintf(buf, buf_size, "%s", _type_map[info->cell_type]);

if(bytes_needed > buf_size)
ERROR_RETURN_LOG(int, "The output buffer is too small");

return 0;
}
33 changes: 33 additions & 0 deletions lib/psnl/include/psnl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Copyright (C) 2018, Hao Hou
**/

/**
* @brief The Plumber Standard Numeric Library
* @details This is the library that is used for high performance numeric computing
* on the Plumber platform
* @file psnl/include/psnl.h.
**/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>

#include <pservlet.h>
#include <pstd.h>

#ifndef __PSNL_H__
#define __PSNL_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <psnl/dim.h>

#include <psnl/cpu/field.h>

#include <psnl/expr.h>
#ifdef __cplusplus
}
#endif
#endif /*__PSNL_H__ */
Loading