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.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +61 -0
  3. data/Gemfile +5 -0
  4. data/History.md +0 -0
  5. data/README.md +5 -0
  6. data/Rakefile +105 -0
  7. data/ext/ruby_gumath/examples.c +126 -0
  8. data/ext/ruby_gumath/extconf.rb +97 -0
  9. data/ext/ruby_gumath/functions.c +106 -0
  10. data/ext/ruby_gumath/gufunc_object.c +79 -0
  11. data/ext/ruby_gumath/gufunc_object.h +55 -0
  12. data/ext/ruby_gumath/gumath/AUTHORS.txt +5 -0
  13. data/ext/ruby_gumath/gumath/INSTALL.txt +42 -0
  14. data/ext/ruby_gumath/gumath/LICENSE.txt +29 -0
  15. data/ext/ruby_gumath/gumath/MANIFEST.in +3 -0
  16. data/ext/ruby_gumath/gumath/Makefile.in +62 -0
  17. data/ext/ruby_gumath/gumath/README.rst +20 -0
  18. data/ext/ruby_gumath/gumath/config.guess +1530 -0
  19. data/ext/ruby_gumath/gumath/config.h.in +52 -0
  20. data/ext/ruby_gumath/gumath/config.sub +1782 -0
  21. data/ext/ruby_gumath/gumath/configure +5049 -0
  22. data/ext/ruby_gumath/gumath/configure.ac +167 -0
  23. data/ext/ruby_gumath/gumath/doc/_static/copybutton.js +66 -0
  24. data/ext/ruby_gumath/gumath/doc/conf.py +26 -0
  25. data/ext/ruby_gumath/gumath/doc/gumath/functions.rst +62 -0
  26. data/ext/ruby_gumath/gumath/doc/gumath/index.rst +26 -0
  27. data/ext/ruby_gumath/gumath/doc/index.rst +45 -0
  28. data/ext/ruby_gumath/gumath/doc/libgumath/data-structures.rst +130 -0
  29. data/ext/ruby_gumath/gumath/doc/libgumath/functions.rst +78 -0
  30. data/ext/ruby_gumath/gumath/doc/libgumath/index.rst +25 -0
  31. data/ext/ruby_gumath/gumath/doc/libgumath/kernels.rst +41 -0
  32. data/ext/ruby_gumath/gumath/doc/releases/index.rst +11 -0
  33. data/ext/ruby_gumath/gumath/install-sh +527 -0
  34. data/ext/ruby_gumath/gumath/libgumath/Makefile.in +170 -0
  35. data/ext/ruby_gumath/gumath/libgumath/Makefile.vc +160 -0
  36. data/ext/ruby_gumath/gumath/libgumath/apply.c +201 -0
  37. data/ext/ruby_gumath/gumath/libgumath/extending/bfloat16.c +130 -0
  38. data/ext/ruby_gumath/gumath/libgumath/extending/examples.c +176 -0
  39. data/ext/ruby_gumath/gumath/libgumath/extending/graph.c +393 -0
  40. data/ext/ruby_gumath/gumath/libgumath/extending/pdist.c +140 -0
  41. data/ext/ruby_gumath/gumath/libgumath/extending/quaternion.c +156 -0
  42. data/ext/ruby_gumath/gumath/libgumath/func.c +177 -0
  43. data/ext/ruby_gumath/gumath/libgumath/gumath.h +205 -0
  44. data/ext/ruby_gumath/gumath/libgumath/kernels/binary.c +547 -0
  45. data/ext/ruby_gumath/gumath/libgumath/kernels/unary.c +449 -0
  46. data/ext/ruby_gumath/gumath/libgumath/nploops.c +219 -0
  47. data/ext/ruby_gumath/gumath/libgumath/tbl.c +223 -0
  48. data/ext/ruby_gumath/gumath/libgumath/thread.c +175 -0
  49. data/ext/ruby_gumath/gumath/libgumath/xndloops.c +130 -0
  50. data/ext/ruby_gumath/gumath/python/extending.py +24 -0
  51. data/ext/ruby_gumath/gumath/python/gumath/__init__.py +74 -0
  52. data/ext/ruby_gumath/gumath/python/gumath/_gumath.c +577 -0
  53. data/ext/ruby_gumath/gumath/python/gumath/examples.c +93 -0
  54. data/ext/ruby_gumath/gumath/python/gumath/functions.c +77 -0
  55. data/ext/ruby_gumath/gumath/python/gumath/pygumath.h +95 -0
  56. data/ext/ruby_gumath/gumath/python/test_gumath.py +405 -0
  57. data/ext/ruby_gumath/gumath/setup.py +298 -0
  58. data/ext/ruby_gumath/gumath/vcbuild/INSTALL.txt +36 -0
  59. data/ext/ruby_gumath/gumath/vcbuild/vcbuild32.bat +21 -0
  60. data/ext/ruby_gumath/gumath/vcbuild/vcbuild64.bat +21 -0
  61. data/ext/ruby_gumath/gumath/vcbuild/vcclean.bat +10 -0
  62. data/ext/ruby_gumath/gumath/vcbuild/vcdistclean.bat +11 -0
  63. data/ext/ruby_gumath/include/gumath.h +205 -0
  64. data/ext/ruby_gumath/include/ruby_gumath.h +41 -0
  65. data/ext/ruby_gumath/lib/libgumath.a +0 -0
  66. data/ext/ruby_gumath/lib/libgumath.so +1 -0
  67. data/ext/ruby_gumath/lib/libgumath.so.0 +1 -0
  68. data/ext/ruby_gumath/lib/libgumath.so.0.2.0dev3 +0 -0
  69. data/ext/ruby_gumath/ruby_gumath.c +295 -0
  70. data/ext/ruby_gumath/ruby_gumath.h +41 -0
  71. data/ext/ruby_gumath/ruby_gumath_internal.h +45 -0
  72. data/ext/ruby_gumath/util.c +68 -0
  73. data/ext/ruby_gumath/util.h +48 -0
  74. data/gumath.gemspec +47 -0
  75. data/lib/gumath.rb +7 -0
  76. data/lib/gumath/version.rb +5 -0
  77. data/lib/ruby_gumath.so +0 -0
  78. 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
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
4
+ gem 'ndtypes', path: "/home/sameer/gitrepos/plures-ruby/ndtypes"
5
+ gem 'xnd', path: "/home/sameer/gitrepos/plures-ruby/xnd"
data/History.md ADDED
File without changes
data/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # Introduction
2
+
3
+ gumath is a library for computational kernels that target XND containers.
4
+
5
+
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
+ }