Skip to content

Commit

Permalink
add basic support for Go
Browse files Browse the repository at this point in the history
  • Loading branch information
vigsterkr committed Feb 12, 2018
1 parent d1763b8 commit 5ee18e1
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 6 deletions.
9 changes: 8 additions & 1 deletion CMakeLists.txt
Expand Up @@ -97,7 +97,7 @@ SET(LIBSHOGUN_SRC_DIR ${CMAKE_SOURCE_DIR}/src/shogun)
SET(COMMON_INTERFACE_SRC_DIR ${CMAKE_SOURCE_DIR}/src/interfaces/swig/)

SET(AVAILABLE_INTERFACES
INTERFACE_PYTHON;INTERFACE_OCTAVE;INTERFACE_JAVA;INTERFACE_PERL;INTERFACE_RUBY;INTERFACE_CSHARP;INTERFACE_R;INTERFACE_LUA;INTERFACE_SCALA)
INTERFACE_PYTHON;INTERFACE_OCTAVE;INTERFACE_JAVA;INTERFACE_PERL;INTERFACE_RUBY;INTERFACE_CSHARP;INTERFACE_R;INTERFACE_LUA;INTERFACE_SCALA;INTERFACE_GO)
SET(INTERFACE_PYTHON_DESCRIPTION "Python")
SET(INTERFACE_OCTAVE_DESCRIPTION "Octave")
SET(INTERFACE_JAVA_DESCRIPTION "Java")
Expand All @@ -107,6 +107,7 @@ SET(INTERFACE_CSHARP_DESCRIPTION "C#")
SET(INTERFACE_R_DESCRIPTION "R")
SET(INTERFACE_LUA_DESCRIPTION "Lua")
SET(INTERFACE_SCALA_DESCRIPTION "Scala")
SET(INTERFACE_GO_DESCRIPTION "Go")
SET(LIBSHOGUN ON CACHE BOOL "Compile shogun library")

IsAnyTrue("${AVAILABLE_INTERFACES}" ANY_INTERFACE_ENABLED)
Expand Down Expand Up @@ -507,6 +508,12 @@ IF (INTERFACE_PERL)
ENDIF()
ENDIF()

IF (INTERFACE_GO)
IF(EXISTS ${CMAKE_SOURCE_DIR}/src/interfaces/go)
add_subdirectory(${CMAKE_SOURCE_DIR}/src/interfaces/go)
ENDIF()
ENDIF()

IF (SVMLight)
MESSAGE(STATUS ${SVMLightWarning})
ENDIF()
Expand Down
12 changes: 12 additions & 0 deletions cmake/FindGo.cmake
@@ -0,0 +1,12 @@
find_program(GO NAMES go)

if (GO)
execute_process(COMMAND ${GO} version ERROR_QUIET OUTPUT_VARIABLE GO_VERSION_OUT)
string(REGEX MATCH "go[ \t]+version[ \t]+go([0-9.]+)" _go_version "${GO_VERSION_OUT}")
SET(GO_VERSION "${CMAKE_MATCH_1}")
endif()

# handle REQUIRED and QUIET options
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Go REQUIRED_VARS GO GO_VERSION)
mark_as_advanced (GO)
2 changes: 1 addition & 1 deletion cmake/ShogunInterfaces.cmake
Expand Up @@ -39,7 +39,7 @@ ADD_CUSTOM_TARGET(${INTERFACE_TARGET_SRC}
INCLUDE(${SWIG_USE_FILE})
SET_SOURCE_FILES_PROPERTIES(shogun.i PROPERTIES CPLUSPLUS ON)
IF(DEFINED TARGET_SWIGFLAGS)
SET_SOURCE_FILES_PROPERTIES(shogun.i PROPERTIES SWIG_FLAGS ${TARGET_SWIGFLAGS})
SET_PROPERTY(SOURCE shogun.i PROPERTY SWIG_FLAGS ${TARGET_SWIGFLAGS})
ENDIF()
SET(SWIG_MODULE_${INTERFACE_NAME}_EXTRA_DEPS ${INTERFACE_FILES})
SWIG_ADD_MODULE(${INTERFACE_TARGET} ${INTERFACE_NAME} shogun.i sg_print_functions.cpp)
Expand Down
19 changes: 19 additions & 0 deletions src/interfaces/go/CMakeLists.txt
@@ -0,0 +1,19 @@
FIND_PACKAGE(GO REQUIRED)

include(ShogunInterfaces)

if (${GO_VERSION} VERSION_GREATER 1.2)
LIST(APPEND TARGET_SWIGFLAGS -cgo)
endif()

# intsize
LIST(APPEND TARGET_SWIGFLAGS -intgosize)
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
LIST(APPEND TARGET_SWIGFLAGS 64)
ELSE()
LIST(APPEND TARGET_SWIGFLAGS 32)
ENDIF()

GENERATE_INTERFACE_TARGET(go ${CMAKE_CURRENT_SOURCE_DIR} "")

SET(INTERFACE_GO_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE)
17 changes: 17 additions & 0 deletions src/interfaces/go/sg_print_functions.cpp
@@ -0,0 +1,17 @@
#include <shogun/io/SGIO.h>
#include <stdio.h>

void sg_global_print_message(FILE* target, const char* str)
{
fprintf(target, "%s", str);
}

void sg_global_print_warning(FILE* target, const char* str)
{
fprintf(target, "%s", str);
}

void sg_global_print_error(FILE* target, const char* str)
{
fprintf(target, "%s", str);
}
99 changes: 99 additions & 0 deletions src/interfaces/go/swig_typemaps.i
@@ -0,0 +1,99 @@
/*
* This software is distributed under BSD 3-clause license (see LICENSE file).
*
* Authors: Viktor Gal
*/

%define TYPEMAP_SGVECTOR(go_type, sg_type)

%typemap(gotype) shogun::SGVector<sg_type> %{[]go_type%}

%typemap(in) shogun::SGVector<sg_type>
{
sg_type* copy = SG_MALLOC(sg_type, $input.len);
sg_memcpy(copy, $input.array, $input.len);
$1 = shogun::SGVector<sg_type>((SGTYPE *)copy, $input.len);
}

%typemap(out) shogun::SGVector<sg_type>
{
$result.array = SG_MALLOC(sg_type, $1.vlen);
$result.len = $1.vlen;
$result.cap = $1.vlen;
sg_memcpy($result.array, $1.vector, $1.vlen);
}
%enddef

/* Define concrete examples of the TYPEMAP_SG_VECTOR macros */
TYPEMAP_SGVECTOR(bool, bool)
TYPEMAP_SGVECTOR(char, int8)
TYPEMAP_SGVECTOR(byte, uint8_t)
TYPEMAP_SGVECTOR(int16, int16_t)
TYPEMAP_SGVECTOR(uint16, uint16_t)
TYPEMAP_SGVECTOR(int, int32_t)
TYPEMAP_SGVECTOR(uint, uint32_t)
TYPEMAP_SGVECTOR(int64, int64_t)
TYPEMAP_SGVECTOR(uint64, uint64_t)
TYPEMAP_SGVECTOR(float32, float32_t)
TYPEMAP_SGVECTOR(float64, float64_t)

#undef TYPEMAP_SGVECTOR

%define TYPEMAP_SGMATRIX(go_type, sg_type)
%typemap(gotype) shogun::SGMatrix<sg_type> %{[][]go_type%}

%typemap(in) shogun::SGMatrix<sg_type> {
index_t cols = 0;
for (auto i = 0; i < $input.len; i++)
{
_goslice_ *row = &((_goslice_ *)$input.array)[i];
if (row->len > cols) cols = row->len;
}

sg_type* array = SG_MALLOC(sg_type, $input.len * cols);
for (auto i = 0; i < $input.len; i++)
{
_goslice_ *row = &((_goslice_ *)$input.array)[i];
sg_memcpy((void *)(array + (cols * i)), (sg_type *)row->array, row->len * sizeof(float));
}
$1 = shogun::SGMatrix<sg_type>((sg_type*)array, $input.len, cols, true);
}

%typemap(out) shogun::SGMatrix<sg_type> {
sg_type* matrix = $1.matrix;
auto rows = $1.num_rows;
auto cols = $1.num_cols;

_goslice_ *a;
$result.array = SG_MALLOC($1.num_rows, sizeof(_goslice_));
for (auto i = 0; i < rows; ++i)
{
_goslice_ *row = &((_goslice_ *)$result.array)[i];
row->array = SG_MALLOC(sg_type, cols);
row->len = cols;
row->cap = cols;
for (auto j = 0; j < cols; ++j)
{
((sg_type *)row->array)[j] = matrix[j+i*num_feat];
}
}
$result.len = rows;
$result.cap = $result.len;
}

%enddef

/* Define concrete examples of the TYPEMAP_SGMATRIX macros */
TYPEMAP_SGMATRIX(bool, bool)
TYPEMAP_SGMATRIX(char, int8)
TYPEMAP_SGMATRIX(byte, uint8_t)
TYPEMAP_SGMATRIX(int16, int16_t)
TYPEMAP_SGMATRIX(uint16, uint16_t)
TYPEMAP_SGMATRIX(int, int32_t)
TYPEMAP_SGMATRIX(uint, uint32_t)
TYPEMAP_SGMATRIX(int64, int64_t)
TYPEMAP_SGMATRIX(uint64, uint64_t)
TYPEMAP_SGMATRIX(float32, float32_t)
TYPEMAP_SGMATRIX(float64, float64_t)

#undef TYPEMAP_SGMATRIX
3 changes: 2 additions & 1 deletion src/interfaces/java/CMakeLists.txt
Expand Up @@ -13,7 +13,8 @@ ELSE()
"It is required for java interface!")
ENDIF()

SET(TARGET_SWIGFLAGS "-package\;org.shogun")
LIST(APPEND TARGET_SWIGFLAGS "-package")
LIST(APPEND TARGET_SWIGFLAGS "org.shogun")

include(ShogunInterfaces)
include_directories(${JNI_INCLUDE_DIRS})
Expand Down
5 changes: 2 additions & 3 deletions src/interfaces/python/CMakeLists.txt
Expand Up @@ -6,11 +6,10 @@ FIND_PACKAGE(NumPy REQUIRED)
SET(HAVE_PYTHON 1)

#custom swig flags for python interface
SET(TARGET_SWIGFLAGS "-builtin" "-modern" "-modernargs" "-threads")
IF(${PYTHON_VERSION_MAJOR} VERSION_EQUAL 3)
SET(TARGET_SWIGFLAGS "-builtin\;-modern\;-modernargs\;-threads\;-py3")
LIST(APPEND TARGET_SWIGFLAGS "-py3")
SET(PYTHON3 1)
ELSE()
SET(TARGET_SWIGFLAGS "-builtin\;-modern\;-modernargs\;-threads")
ENDIF()

# SWIG-generated Python-wrappers fail to build
Expand Down

0 comments on commit 5ee18e1

Please sign in to comment.