gumath 0.2.0dev5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
}
|