gumath 0.2.0dev5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +61 -0
- data/Gemfile +5 -0
- data/History.md +0 -0
- data/README.md +5 -0
- data/Rakefile +105 -0
- data/ext/ruby_gumath/examples.c +126 -0
- data/ext/ruby_gumath/extconf.rb +97 -0
- data/ext/ruby_gumath/functions.c +106 -0
- data/ext/ruby_gumath/gufunc_object.c +79 -0
- data/ext/ruby_gumath/gufunc_object.h +55 -0
- data/ext/ruby_gumath/gumath/AUTHORS.txt +5 -0
- data/ext/ruby_gumath/gumath/INSTALL.txt +42 -0
- data/ext/ruby_gumath/gumath/LICENSE.txt +29 -0
- data/ext/ruby_gumath/gumath/MANIFEST.in +3 -0
- data/ext/ruby_gumath/gumath/Makefile.in +62 -0
- data/ext/ruby_gumath/gumath/README.rst +20 -0
- data/ext/ruby_gumath/gumath/config.guess +1530 -0
- data/ext/ruby_gumath/gumath/config.h.in +52 -0
- data/ext/ruby_gumath/gumath/config.sub +1782 -0
- data/ext/ruby_gumath/gumath/configure +5049 -0
- data/ext/ruby_gumath/gumath/configure.ac +167 -0
- data/ext/ruby_gumath/gumath/doc/_static/copybutton.js +66 -0
- data/ext/ruby_gumath/gumath/doc/conf.py +26 -0
- data/ext/ruby_gumath/gumath/doc/gumath/functions.rst +62 -0
- data/ext/ruby_gumath/gumath/doc/gumath/index.rst +26 -0
- data/ext/ruby_gumath/gumath/doc/index.rst +45 -0
- data/ext/ruby_gumath/gumath/doc/libgumath/data-structures.rst +130 -0
- data/ext/ruby_gumath/gumath/doc/libgumath/functions.rst +78 -0
- data/ext/ruby_gumath/gumath/doc/libgumath/index.rst +25 -0
- data/ext/ruby_gumath/gumath/doc/libgumath/kernels.rst +41 -0
- data/ext/ruby_gumath/gumath/doc/releases/index.rst +11 -0
- data/ext/ruby_gumath/gumath/install-sh +527 -0
- data/ext/ruby_gumath/gumath/libgumath/Makefile.in +170 -0
- data/ext/ruby_gumath/gumath/libgumath/Makefile.vc +160 -0
- data/ext/ruby_gumath/gumath/libgumath/apply.c +201 -0
- data/ext/ruby_gumath/gumath/libgumath/extending/bfloat16.c +130 -0
- data/ext/ruby_gumath/gumath/libgumath/extending/examples.c +176 -0
- data/ext/ruby_gumath/gumath/libgumath/extending/graph.c +393 -0
- data/ext/ruby_gumath/gumath/libgumath/extending/pdist.c +140 -0
- data/ext/ruby_gumath/gumath/libgumath/extending/quaternion.c +156 -0
- data/ext/ruby_gumath/gumath/libgumath/func.c +177 -0
- data/ext/ruby_gumath/gumath/libgumath/gumath.h +205 -0
- data/ext/ruby_gumath/gumath/libgumath/kernels/binary.c +547 -0
- data/ext/ruby_gumath/gumath/libgumath/kernels/unary.c +449 -0
- data/ext/ruby_gumath/gumath/libgumath/nploops.c +219 -0
- data/ext/ruby_gumath/gumath/libgumath/tbl.c +223 -0
- data/ext/ruby_gumath/gumath/libgumath/thread.c +175 -0
- data/ext/ruby_gumath/gumath/libgumath/xndloops.c +130 -0
- data/ext/ruby_gumath/gumath/python/extending.py +24 -0
- data/ext/ruby_gumath/gumath/python/gumath/__init__.py +74 -0
- data/ext/ruby_gumath/gumath/python/gumath/_gumath.c +577 -0
- data/ext/ruby_gumath/gumath/python/gumath/examples.c +93 -0
- data/ext/ruby_gumath/gumath/python/gumath/functions.c +77 -0
- data/ext/ruby_gumath/gumath/python/gumath/pygumath.h +95 -0
- data/ext/ruby_gumath/gumath/python/test_gumath.py +405 -0
- data/ext/ruby_gumath/gumath/setup.py +298 -0
- data/ext/ruby_gumath/gumath/vcbuild/INSTALL.txt +36 -0
- data/ext/ruby_gumath/gumath/vcbuild/vcbuild32.bat +21 -0
- data/ext/ruby_gumath/gumath/vcbuild/vcbuild64.bat +21 -0
- data/ext/ruby_gumath/gumath/vcbuild/vcclean.bat +10 -0
- data/ext/ruby_gumath/gumath/vcbuild/vcdistclean.bat +11 -0
- data/ext/ruby_gumath/include/gumath.h +205 -0
- data/ext/ruby_gumath/include/ruby_gumath.h +41 -0
- data/ext/ruby_gumath/lib/libgumath.a +0 -0
- data/ext/ruby_gumath/lib/libgumath.so +1 -0
- data/ext/ruby_gumath/lib/libgumath.so.0 +1 -0
- data/ext/ruby_gumath/lib/libgumath.so.0.2.0dev3 +0 -0
- data/ext/ruby_gumath/ruby_gumath.c +295 -0
- data/ext/ruby_gumath/ruby_gumath.h +41 -0
- data/ext/ruby_gumath/ruby_gumath_internal.h +45 -0
- data/ext/ruby_gumath/util.c +68 -0
- data/ext/ruby_gumath/util.h +48 -0
- data/gumath.gemspec +47 -0
- data/lib/gumath.rb +7 -0
- data/lib/gumath/version.rb +5 -0
- data/lib/ruby_gumath.so +0 -0
- metadata +206 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8a56c97c8de3fc82fc684c10a6a9910963c69214
|
4
|
+
data.tar.gz: f7e8e3053c3ff0d74c7b33dbd1e9668a892ffc70
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a33696aa82d1facedba27585e45b907cf287ba58407cd2856e127ded4e24529879f0cbf70b3ac1b931f661bbb7066fc1b461fede74b7b4602a463422c3c1ca1c
|
7
|
+
data.tar.gz: 21f198e731872448efde3548493c0bdd9c2f8e696aeca57786f130f812946da32c0f374e88bdaf17289d3691f5d7fa6c7c8a172bd0da2cb87b6ad5f9c85f23c3
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# Details
|
2
|
+
|
3
|
+
## Functioning of libgumath
|
4
|
+
|
5
|
+
Gumath is a wrapper over libgumath. The docs for libgumath can be found [here](https://xnd.readthedocs.io/en/latest/libgumath/index.html).
|
6
|
+
|
7
|
+
It allows users to write [multiple dispatch](https://en.wikipedia.org/wiki/Multiple_dispatch) functions for XND containers.
|
8
|
+
Multiple dispatch can be thought of as the concept behind function overloading in
|
9
|
+
languages like C++. However the major difference is that the function call is made
|
10
|
+
according to the run time types of the arguments in case of multiple dispatch whereas
|
11
|
+
in overloading it is determined at compile-time and the types of arguments determine
|
12
|
+
the 'signature' of the function. [This answer](https://cs.stackexchange.com/questions/4660/difference-between-multimethods-and-overloading) sheds some light on the differences
|
13
|
+
between the two. Here's [another link](http://wiki.c2.com/?MultiMethods) on the same topic.
|
14
|
+
|
15
|
+
This functionality is absent in Ruby because in Ruby we don't care about the type of
|
16
|
+
the arguments of a function when calling it (aka duck typing).
|
17
|
+
|
18
|
+
Gumath functions (or 'kernels') are functions that can accept XND objects of multiple
|
19
|
+
data types and compute the result depending on what kind of data type is sent in. The
|
20
|
+
data type is known only at run time (like determining whether a container is of type
|
21
|
+
float32 or int etc.) and the same function can handle all sorts of data types.
|
22
|
+
|
23
|
+
Libgumath stores functions in a look-up table. Each Ruby module containing functions
|
24
|
+
should have its own look-up table. A prototype of adding gumath kernels to a Ruby module
|
25
|
+
`Gumath::Functions` can be found in the functions.c file in this repo.
|
26
|
+
|
27
|
+
An XND kernel has the following function signature:
|
28
|
+
```
|
29
|
+
typedef int (* gm_xnd_kernel_t)(xnd_t stack[], ndt_context_t *ctx);
|
30
|
+
```
|
31
|
+
|
32
|
+
## Interfacing libgumath with Ruby
|
33
|
+
|
34
|
+
Unlike in Python, Ruby functions are not first-class objects and therefore we cannot create
|
35
|
+
a 'callable' object like we can in Python. Since libgumath kernels are run-time constructs
|
36
|
+
it is difficult to dynamically add these functions to a Ruby module at runtime since unlike
|
37
|
+
Ruby, C cannot generate new functions at run-time.
|
38
|
+
|
39
|
+
However, Ruby does have support for lambdas and we can store the function implementations
|
40
|
+
inside lambdas. These lambdas are stored in module variables that are of the same name
|
41
|
+
as the function name that they implement. When the user calls the lambda with the `call` method
|
42
|
+
or `.` syntax, the lambda will be passed the argument (after some conversion) and will
|
43
|
+
return the result given by the gumath kernel.
|
44
|
+
|
45
|
+
Another approach is to have a Hash of methods and their corresponding implementations
|
46
|
+
stored inside each module. Whenever a method is called on the module, it will routed to
|
47
|
+
the method_missing in the class, which will lookup the hash and call the appropriate
|
48
|
+
lambda. This seems like the better approach since the user no longer needs to know that
|
49
|
+
the functions that they're calling inside the module are in fact lambdas.
|
50
|
+
|
51
|
+
So each module that contains gumath methods should have a hash called `gumath_functions`
|
52
|
+
that stores function names as keys (as symbols) and the corresponding values as objects
|
53
|
+
of type `GufuncObject`. This `GufuncObject` will have a method `call` defined on it that
|
54
|
+
will be called by the `method_missing` when that object is called. The only extra overhead
|
55
|
+
will be that of a Hash lookup (O(1) time) and calling an Ruby method `call`.
|
56
|
+
|
57
|
+
## Calling gumath kernels
|
58
|
+
|
59
|
+
Gumath kernels can be called by using the `gm_apply` function and passing a pointer to
|
60
|
+
the function along with its arguments. Its multi-threaded counterpart, `gm_apply_thread`
|
61
|
+
can also be used for this purpose.
|
data/Gemfile
ADDED
data/History.md
ADDED
File without changes
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/extensiontask'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'bundler/gem_tasks'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'gumath/version.rb'
|
7
|
+
|
8
|
+
gemspec = eval(IO.read('gumath.gemspec'))
|
9
|
+
|
10
|
+
ext_name = "ruby_gumath"
|
11
|
+
Rake::ExtensionTask.new(ext_name, gemspec) do |ext|
|
12
|
+
ext.ext_dir = "ext/#{ext_name}"
|
13
|
+
ext.source_pattern = "**/*.{c,h}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def run *cmd
|
17
|
+
sh(cmd.join(" "))
|
18
|
+
end
|
19
|
+
|
20
|
+
task :console do
|
21
|
+
cmd = ['irb', "-r './lib/gumath.rb'"]
|
22
|
+
run(*cmd)
|
23
|
+
end
|
24
|
+
|
25
|
+
task :pry do
|
26
|
+
cmd = ['pry', "-r './lib/gumath.rb'"]
|
27
|
+
run(*cmd)
|
28
|
+
end
|
29
|
+
|
30
|
+
Rake::TestTask.new(:test) do |t|
|
31
|
+
t.libs << "test"
|
32
|
+
t.libs << "lib"
|
33
|
+
t.test_files = FileList['test/**/test_*.rb']
|
34
|
+
end
|
35
|
+
|
36
|
+
BASEDIR = Pathname( __FILE__ ).dirname.relative_path_from( Pathname.pwd )
|
37
|
+
TESTDIR = BASEDIR + 'test'
|
38
|
+
|
39
|
+
VALGRIND_OPTIONS = [
|
40
|
+
"--tool=memcheck",
|
41
|
+
#"--leak-check=yes",
|
42
|
+
"--num-callers=15",
|
43
|
+
#"--error-limit=no",
|
44
|
+
"--partial-loads-ok=yes",
|
45
|
+
"--undef-value-errors=no" #,
|
46
|
+
#"--dsymutil=yes"
|
47
|
+
]
|
48
|
+
|
49
|
+
VALGRIND_MEMORYFILL_OPTIONS = [
|
50
|
+
"--freelist-vol=100000000",
|
51
|
+
"--malloc-fill=6D",
|
52
|
+
"--free-fill=66 ",
|
53
|
+
]
|
54
|
+
|
55
|
+
# partial-loads-ok and undef-value-errors necessary to ignore
|
56
|
+
# spurious (and eminently ignorable) warnings from the ruby
|
57
|
+
# interpreter
|
58
|
+
|
59
|
+
desc "Run specs under Valgrind."
|
60
|
+
task :valgrind => [ :compile ] do |task|
|
61
|
+
cmd = [ 'valgrind' ] + VALGRIND_OPTIONS
|
62
|
+
cmd += [" rake test "]
|
63
|
+
run( *cmd )
|
64
|
+
end
|
65
|
+
|
66
|
+
LEAKCHECK_CMD = [ 'ruby', '-Ilib:ext', "#{TESTDIR}/leakcheck.rb" ]
|
67
|
+
|
68
|
+
desc "Run leakcheck script."
|
69
|
+
task :leakcheck => [ :compile ] do |task|
|
70
|
+
cmd = [ 'valgrind' ] + VALGRIND_OPTIONS
|
71
|
+
cmd += LEAKCHECK_CMD
|
72
|
+
run( *cmd )
|
73
|
+
end
|
74
|
+
|
75
|
+
task :clobber do |task|
|
76
|
+
[
|
77
|
+
"ext/#{ext_name}/include",
|
78
|
+
"ext/#{ext_name}/share",
|
79
|
+
"ext/#{ext_name}/lib",
|
80
|
+
].each do |f|
|
81
|
+
puts "deleting folder #{f}..."
|
82
|
+
FileUtils.rm_rf(f)
|
83
|
+
end
|
84
|
+
|
85
|
+
Dir.chdir("ext/#{ext_name}/gumath/libgumath/") do
|
86
|
+
system("make clean")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
task :develop do
|
91
|
+
ext_gumath = "ext/ruby_gumath/gumath"
|
92
|
+
puts "deleting previously created #{ext_gumath} directory..."
|
93
|
+
FileUtils.rm_rf(ext_gumath)
|
94
|
+
Dir.mkdir(ext_gumath)
|
95
|
+
|
96
|
+
puts "cloning gumath repo into ext/ folder..."
|
97
|
+
system("git clone https://github.com/plures/gumath #{ext_gumath}")
|
98
|
+
|
99
|
+
Dir.chdir(ext_gumath) do
|
100
|
+
system("git checkout #{Gumath::COMMIT}")
|
101
|
+
end
|
102
|
+
|
103
|
+
puts "building gem with rake build..."
|
104
|
+
system("rake build")
|
105
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
/* BSD 3-Clause License
|
2
|
+
*
|
3
|
+
* Copyright (c) 2018, Quansight and Sameer Deshmukh
|
4
|
+
* All rights reserved.
|
5
|
+
*
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
7
|
+
* modification, are permitted provided that the following conditions are met:
|
8
|
+
*
|
9
|
+
* * Redistributions of source code must retain the above copyright notice, this
|
10
|
+
* list of conditions and the following disclaimer.
|
11
|
+
*
|
12
|
+
* * Redistributions in binary form must reproduce the above copyright notice,
|
13
|
+
* this list of conditions and the following disclaimer in the documentation
|
14
|
+
* and/or other materials provided with the distribution.
|
15
|
+
*
|
16
|
+
* * Neither the name of the copyright holder nor the names of its
|
17
|
+
* contributors may be used to endorse or promote products derived from
|
18
|
+
* this software without specific prior written permission.
|
19
|
+
*
|
20
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
23
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
24
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
26
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
27
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
28
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
*/
|
31
|
+
#include <ruby.h>
|
32
|
+
#include "ndtypes.h"
|
33
|
+
#include "ruby_ndtypes.h"
|
34
|
+
#include "gumath.h"
|
35
|
+
#include "gufunc_object.h"
|
36
|
+
#include "ruby_gumath.h"
|
37
|
+
#include "util.h"
|
38
|
+
|
39
|
+
/****************************************************************************/
|
40
|
+
/* Static globals */
|
41
|
+
/****************************************************************************/
|
42
|
+
|
43
|
+
/* Function table */
|
44
|
+
static gm_tbl_t *table = NULL;
|
45
|
+
static VALUE mGumath_Examples;
|
46
|
+
static int initialized = 0;
|
47
|
+
|
48
|
+
/****************************************************************************/
|
49
|
+
/* Singleton methods */
|
50
|
+
/****************************************************************************/
|
51
|
+
static VALUE
|
52
|
+
mGumath_Examples_s_method_missing(int argc, VALUE *argv, VALUE module)
|
53
|
+
{
|
54
|
+
VALUE method_name = argv[0];
|
55
|
+
VALUE method_hash = rb_ivar_get(module, GUMATH_FUNCTION_HASH);
|
56
|
+
VALUE gumath_method = rb_hash_aref(method_hash, method_name);
|
57
|
+
int is_present = RTEST(gumath_method);
|
58
|
+
|
59
|
+
if (is_present) {
|
60
|
+
rb_funcall2(gumath_method, rb_intern("call"), argc-1, &argv[1]);
|
61
|
+
}
|
62
|
+
else {
|
63
|
+
VALUE str = rb_funcall(method_name, rb_intern("to_s"), 0, NULL);
|
64
|
+
rb_raise(rb_eNoMethodError, "Method %s not present in this gumath module.",
|
65
|
+
StringValueCStr(str));
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
void
|
70
|
+
Init_gumath_examples(void)
|
71
|
+
{
|
72
|
+
NDT_STATIC_CONTEXT(ctx);
|
73
|
+
|
74
|
+
if (!initialized) {
|
75
|
+
if (!ndt_exists()) {
|
76
|
+
rb_raise(rb_eLoadError, "NDT is needed for making gumath work.");
|
77
|
+
}
|
78
|
+
|
79
|
+
if (!xnd_exists()) {
|
80
|
+
rb_raise(rb_eLoadError, "XND is needed for making gumath work.");
|
81
|
+
}
|
82
|
+
|
83
|
+
table = gm_tbl_new(&ctx);
|
84
|
+
if (table == NULL) {
|
85
|
+
seterr(&ctx);
|
86
|
+
raise_error();
|
87
|
+
}
|
88
|
+
|
89
|
+
/* load custom examples */
|
90
|
+
if (gm_init_example_kernels(table, &ctx) < 0) {
|
91
|
+
seterr(&ctx);
|
92
|
+
raise_error();
|
93
|
+
}
|
94
|
+
|
95
|
+
/* extending examples */
|
96
|
+
if (gm_init_graph_kernels(table, &ctx) < 0) {
|
97
|
+
seterr(&ctx);
|
98
|
+
raise_error();
|
99
|
+
}
|
100
|
+
|
101
|
+
#ifndef _MSC_VER
|
102
|
+
if (gm_init_quaternion_kernels(table, &ctx) < 0) {
|
103
|
+
seterr(&ctx);
|
104
|
+
raise_error();
|
105
|
+
}
|
106
|
+
#endif
|
107
|
+
if (gm_init_pdist_kernels(table, &ctx) < 0) {
|
108
|
+
seterr(&ctx);
|
109
|
+
raise_error();
|
110
|
+
}
|
111
|
+
|
112
|
+
initialized = 1;
|
113
|
+
}
|
114
|
+
|
115
|
+
mGumath_Examples = rb_define_module_under(cGumath, "Examples");
|
116
|
+
rb_ivar_set(mGumath_Examples, GUMATH_FUNCTION_HASH, rb_hash_new());
|
117
|
+
|
118
|
+
if (rb_gumath_add_functions(mGumath_Examples, table) < 0) {
|
119
|
+
mGumath_Examples = Qundef;
|
120
|
+
rb_raise(rb_eLoadError, "failed to load functions into Gumath::Examples module.");
|
121
|
+
}
|
122
|
+
|
123
|
+
/* Singleton methods */
|
124
|
+
rb_define_singleton_method(mGumath_Examples, "method_missing",
|
125
|
+
mGumath_Examples_s_method_missing, -1);
|
126
|
+
}
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
|
3
|
+
def windows?
|
4
|
+
(/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
|
5
|
+
end
|
6
|
+
|
7
|
+
def mac?
|
8
|
+
(/darwin/ =~ RUBY_PLATFORM) != nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def unix?
|
12
|
+
!windows?
|
13
|
+
end
|
14
|
+
|
15
|
+
# ndtypes config
|
16
|
+
|
17
|
+
ndtypes_version = ">= 0.2.0dev5"
|
18
|
+
ndtypes_spec = Gem::Specification.find_by_name("ndtypes", ndtypes_version)
|
19
|
+
ndtypes_extdir = File.join(ndtypes_spec.gem_dir, 'ext', 'ruby_ndtypes')
|
20
|
+
ndtypes_includedir = File.join(ndtypes_extdir, 'include')
|
21
|
+
ndtypes_libdir = File.join(ndtypes_extdir, 'lib')
|
22
|
+
|
23
|
+
find_header("ruby_ndtypes.h", ndtypes_includedir)
|
24
|
+
raise "cannot find ruby_ndtypes.h in path #{ndtypes_includedir}." unless have_header("ruby_ndtypes.h")
|
25
|
+
|
26
|
+
find_header("ndtypes.h", ndtypes_includedir)
|
27
|
+
find_library("ndtypes", nil, ndtypes_libdir)
|
28
|
+
|
29
|
+
dir_config("ndtypes", [ndtypes_includedir], [ndtypes_libdir])
|
30
|
+
|
31
|
+
# xnd config
|
32
|
+
|
33
|
+
xnd_version = ">= 0.2.0dev5"
|
34
|
+
xnd_spec = Gem::Specification.find_by_name("xnd", xnd_version)
|
35
|
+
xnd_extdir = File.join(xnd_spec.gem_dir, 'ext', 'ruby_xnd')
|
36
|
+
xnd_includedir = File.join(xnd_extdir, 'include')
|
37
|
+
xnd_libdir = File.join(xnd_extdir, 'lib')
|
38
|
+
|
39
|
+
find_header("ruby_xnd.h", xnd_includedir)
|
40
|
+
raise "cannot find ruby_xnd.h in path #{xnd_includedir}." unless have_header("ruby_xnd.h")
|
41
|
+
|
42
|
+
find_header("xnd.h", xnd_includedir)
|
43
|
+
find_library("xnd", nil, xnd_libdir)
|
44
|
+
|
45
|
+
dir_config("xnd", [xnd_includedir], [xnd_libdir])
|
46
|
+
|
47
|
+
# gumath config
|
48
|
+
|
49
|
+
puts "compiling libgumath on your machine..."
|
50
|
+
Dir.chdir(File.join(File.dirname(__FILE__) + "/gumath")) do
|
51
|
+
if unix?
|
52
|
+
# ["libgumath", "libgumath/compat", "libgumath/serialize"].each do |f|
|
53
|
+
# Dir.chdir(f) do
|
54
|
+
# Dir.mkdir(".objs") unless Dir.exists? ".objs"
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
ENV['CFLAGS'] = " -I #{xnd_includedir} -I #{ndtypes_includedir} "
|
58
|
+
system("./configure --prefix=#{File.expand_path("../")} --with-docs=no ")
|
59
|
+
system("make")
|
60
|
+
system("make install")
|
61
|
+
elsif windows?
|
62
|
+
raise NotImplementedError, "need to specify build instructions for windows."
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
$INSTALLFILES = [
|
67
|
+
["ruby_gumath.h", "$(archdir)"],
|
68
|
+
["gumath.h", "$(archdir)"]
|
69
|
+
]
|
70
|
+
|
71
|
+
binaries = File.expand_path(File.join(File.dirname(__FILE__) + "/lib/"))
|
72
|
+
headers = File.expand_path(File.join(File.dirname(__FILE__) + "/include/"))
|
73
|
+
$LOAD_PATH << File.expand_path(binaries)
|
74
|
+
append_ldflags("-Wl,-rpath #{binaries}")
|
75
|
+
|
76
|
+
find_library("gumath", nil, binaries)
|
77
|
+
|
78
|
+
find_header("gumath.h", headers)
|
79
|
+
have_header("gumath.h")
|
80
|
+
|
81
|
+
FileUtils.copy_file File.expand_path(File.join(File.dirname(__FILE__) +
|
82
|
+
"/ruby_gumath.h")),
|
83
|
+
"#{headers}/ruby_gumath.h"
|
84
|
+
|
85
|
+
dir_config("gumath", [headers], [binaries])
|
86
|
+
|
87
|
+
# for macOS
|
88
|
+
append_ldflags("-Wl,-rpath #{binaries}")
|
89
|
+
|
90
|
+
basenames = %w{util gufunc_object examples functions ruby_gumath}
|
91
|
+
$objs = basenames.map { |b| "#{b}.o" }
|
92
|
+
$srcs = basenames.map { |b| "#{b}.c" }
|
93
|
+
|
94
|
+
$CFLAGS += " -Wall -O0 -fPIC -g "
|
95
|
+
# FIXME: This is jugaad. Remove on deploy.
|
96
|
+
$libs += " -lndtypes -lxnd -lgumath "
|
97
|
+
create_makefile("ruby_gumath/ruby_gumath")
|
@@ -0,0 +1,106 @@
|
|
1
|
+
/* BSD 3-Clause License
|
2
|
+
*
|
3
|
+
* Copyright (c) 2018, Quansight and Sameer Deshmukh
|
4
|
+
* All rights reserved.
|
5
|
+
*
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
7
|
+
* modification, are permitted provided that the following conditions are met:
|
8
|
+
*
|
9
|
+
* * Redistributions of source code must retain the above copyright notice, this
|
10
|
+
* list of conditions and the following disclaimer.
|
11
|
+
*
|
12
|
+
* * Redistributions in binary form must reproduce the above copyright notice,
|
13
|
+
* this list of conditions and the following disclaimer in the documentation
|
14
|
+
* and/or other materials provided with the distribution.
|
15
|
+
*
|
16
|
+
* * Neither the name of the copyright holder nor the names of its
|
17
|
+
* contributors may be used to endorse or promote products derived from
|
18
|
+
* this software without specific prior written permission.
|
19
|
+
*
|
20
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
23
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
24
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
26
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
27
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
28
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
*/
|
31
|
+
#include "ruby_gumath_internal.h"
|
32
|
+
|
33
|
+
/****************************************************************************/
|
34
|
+
/* Static globals */
|
35
|
+
/****************************************************************************/
|
36
|
+
|
37
|
+
/* Function table */
|
38
|
+
static gm_tbl_t *table = NULL;
|
39
|
+
static VALUE mGumath_Functions;
|
40
|
+
static int initialized = 0;
|
41
|
+
|
42
|
+
/****************************************************************************/
|
43
|
+
/* Singleton methods */
|
44
|
+
/****************************************************************************/
|
45
|
+
static VALUE
|
46
|
+
mGumath_Functions_s_method_missing(int argc, VALUE *argv, VALUE module)
|
47
|
+
{
|
48
|
+
VALUE method_name = argv[0];
|
49
|
+
VALUE method_hash = rb_ivar_get(module, GUMATH_FUNCTION_HASH);
|
50
|
+
VALUE gumath_method = rb_hash_aref(method_hash, method_name);
|
51
|
+
int is_present = RTEST(gumath_method);
|
52
|
+
|
53
|
+
if (is_present) {
|
54
|
+
rb_funcall2(gumath_method, rb_intern("call"), argc-1, &argv[1]);
|
55
|
+
}
|
56
|
+
else {
|
57
|
+
VALUE str = rb_funcall(method_name, rb_intern("to_s"), 0, NULL);
|
58
|
+
rb_raise(rb_eNoMethodError, "Method %s not present in this gumath module.",
|
59
|
+
StringValueCStr(str));
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
void Init_gumath_functions(void)
|
64
|
+
{
|
65
|
+
/* Initialize gumath built-in function table. */
|
66
|
+
NDT_STATIC_CONTEXT(ctx);
|
67
|
+
|
68
|
+
if (!initialized) {
|
69
|
+
if (!xnd_exists()) {
|
70
|
+
rb_raise(rb_eLoadError, "XND is needed for making gumath work.");
|
71
|
+
}
|
72
|
+
if (!ndt_exists()) {
|
73
|
+
rb_raise(rb_eLoadError, "NDT is needed for maing gumath work.");
|
74
|
+
}
|
75
|
+
|
76
|
+
table = gm_tbl_new(&ctx);
|
77
|
+
if (table == NULL) {
|
78
|
+
rb_ndtypes_set_error(&ctx);
|
79
|
+
raise_error();
|
80
|
+
}
|
81
|
+
|
82
|
+
if (gm_init_unary_kernels(table, &ctx) < 0) {
|
83
|
+
rb_ndtypes_set_error(&ctx);
|
84
|
+
raise_error();
|
85
|
+
}
|
86
|
+
|
87
|
+
if (gm_init_binary_kernels(table, &ctx) < 0) {
|
88
|
+
rb_ndtypes_set_error(&ctx);
|
89
|
+
raise_error();
|
90
|
+
}
|
91
|
+
|
92
|
+
initialized = 1;
|
93
|
+
}
|
94
|
+
|
95
|
+
mGumath_Functions = rb_define_module_under(cGumath, "Functions");
|
96
|
+
rb_ivar_set(mGumath_Functions, GUMATH_FUNCTION_HASH, rb_hash_new());
|
97
|
+
|
98
|
+
if (rb_gumath_add_functions(mGumath_Functions, table) < 0) {
|
99
|
+
mGumath_Functions = Qundef;
|
100
|
+
rb_raise(rb_eLoadError, "failed to load functions into module Gumath::Functions.");
|
101
|
+
}
|
102
|
+
|
103
|
+
/* Singleton methods */
|
104
|
+
rb_define_singleton_method(mGumath_Functions, "method_missing",
|
105
|
+
mGumath_Functions_s_method_missing, -1);
|
106
|
+
}
|