diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..57a50e6
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,40 @@
+# Contributing to ArrayFire
+
+## Reporting Issues
+
+We both value and encourage the community to provide feedback about using ArrayFire and the issues they are facing.
+The more detailed the information, the easier it is for the developers to resolve the issue.
+
+Issues can span a variety of topics including:
+- Feature requests
+- Bug reports
+- Build Issues
+- Performance improvements
+- New hardware / backend support
+
+We use the github [issue tracker](https://github.com/arrayfire/arrayfire-rb/issues?state=open) to track our issues. Technical issues can also be discussed on our [user forum](https://groups.google.com/forum/#!forum/arrayfire-users).
+
+## Contributing Code
+
+If you want to contribute code, we suggest you use the one of the following methods.
+
+- [Using Github](https://github.com/arrayfire/arrayfire-rb/wiki/Contribute-code-using-github)
+- [Using Email](https://github.com/arrayfire/arrayfire-rb/wiki/Contribute-code-using-email)
+
+Key areas of code contributions include:
+- [New features](https://github.com/arrayfire/arrayfire-rb/issues?q=is%3Aopen+is%3Aissue+label%3Afeature)
+- [Bug fixes](https://github.com/arrayfire/arrayfire-rb/labels/bug)
+- [Style changes](https://github.com/arrayfire/arrayfire-rb/labels/style)
+- [Performance improvements](https://github.com/arrayfire/arrayfire-rb/labels/style)
+- [New tests](https://github.com/arrayfire/arrayfire-rb/labels/test)
+- New examples!
+
+## ArrayFire Based Projects
+
+You can also contribute to ArrayFire by helping out projects that use ArrayFire! For our part, in addition to the ArrayFire library we are also in the process of adding native bindings for numerous language. We currently support
+
+- [Java](https://github.com/arrayfire/arrayfire_java)
+- [R](https://github.com/arrayfire/arrayfire_r)
+- [Fortran](https://github.com/arrayfire/arrayfire_fortran)
+
+If you are experienced in any of these languages, you can help us improve these language bindings. If you prefer a different language that is not in the list, dive in and create a new repo!
diff --git a/LICENSE b/LICENSE
index bbc9e5a..b7b3701 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,6 @@
-Copyright (c) 2016, ArrayFire
+BSD 3-Clause License
+
+Copyright (c) 2016-2017, Prasun Anand and ArrayFire
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -11,7 +13,7 @@ modification, are permitted provided that the following conditions are met:
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
-* Neither the name of arrayfire-rb nor the names of its
+* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
@@ -25,4 +27,3 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/README.md b/README.md
index 1b19ddf..a3ee453 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,45 @@
+
+
+ArrayFire is a general-purpose library that simplifies the process of developing
+software that targets parallel and massively-parallel architectures including
+CPUs, GPUs, and other hardware acceleration devices.
+
# Ruby wrapper for ArrayFire
[](https://gitter.im/arrayfire/arrayfire-ruby)
Ruby bindings are a work in progress and are not production ready yet.
-## Build from source
+## Installation
+
```sh
git clone https://github.com/arrayfire/arrayfire-rb
+cd arrayfire/
+gem install bundler
bundle install
rake compile
```
+
+Run the tests using
+
+```sh
+rake test
+```
+
+If you want to try out the code without installing:
+
+```sh
+rake pry
+```
+
+To install:
+
+```sh
+rake install
+```
+
+# LICENSE
+
+This software is distributed under the [BSD 3-Clause License](LICENSE).
+
+Copyright © 2017, Prasun Anand and ArrayFire
diff --git a/Rakefile b/Rakefile
index 08c84f8..a210642 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,5 +1,8 @@
+require "bundler/gem_tasks"
require 'rake'
require 'rake/extensiontask'
+require "rake/testtask"
+require "rdoc/task"
Rake::ExtensionTask.new do |ext|
ext.name = 'arrayfire'
@@ -21,3 +24,16 @@ end
def run(*cmd)
sh(cmd.join(' '))
end
+
+RDoc::Task.new do |rdoc|
+ rdoc.main = "README.md"
+ rdoc.rdoc_files.include(%w{README.md LICENSE CONTRIBUTING.md lib ext})
+end
+
+Rake::TestTask.new(:test) do |t|
+ t.libs << "test"
+ t.libs << "lib"
+ t.test_files = FileList['test/**/*_test.rb']
+end
+
+task :default => :test
diff --git a/arrayfire.gemspec b/arrayfire.gemspec
index 2f0ec5f..21de1da 100644
--- a/arrayfire.gemspec
+++ b/arrayfire.gemspec
@@ -1,20 +1,37 @@
+# coding: utf-8
+$:.unshift File.expand_path("../lib", __FILE__)
+
+require 'arrayfire/version.rb'
+
+ArrayFire::DESCRIPTION = < 0'
gem.add_development_dependency 'bundler', '~>1.6'
- gem.add_development_dependency 'json'
+ gem.add_development_dependency 'json', '~> 0'
gem.add_development_dependency 'pry', '~>0.10'
gem.add_development_dependency 'rake', '~>10.3'
gem.add_development_dependency 'rake-compiler', '~>0.8'
gem.add_development_dependency 'rdoc', '~>4.0', '>=4.0.1'
- gem.add_development_dependency 'rspec', '~>2.14'
-end
+ gem.add_development_dependency "minitest", "~> 5.0"
+
+ gem.add_development_dependency 'nmatrix', '~> 0.2.1'
+end
\ No newline at end of file
diff --git a/examples/benchmarks/blas.rb b/examples/benchmarks/blas.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/benchmarks/cg.rb b/examples/benchmarks/cg.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/benchmarks/fft.rb b/examples/benchmarks/fft.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/benchmarks/pi.rb b/examples/benchmarks/pi.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/computer_vision/fast.rb b/examples/computer_vision/fast.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/computer_vision/harris.rb b/examples/computer_vision/harris.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/computer_vision/matching.rb b/examples/computer_vision/matching.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/computer_vision/susan.rb b/examples/computer_vision/susan.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/financial/black_scholes_options.rb b/examples/financial/black_scholes_options.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/financial/heston_model.rb b/examples/financial/heston_model.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/financial/monte_carlo_options.rb b/examples/financial/monte_carlo_options.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/getting_started/convolve.rb b/examples/getting_started/convolve.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/getting_started/integer.rb b/examples/getting_started/integer.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/getting_started/rainfall.rb b/examples/getting_started/rainfall.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/getting_started/vectorize.rb b/examples/getting_started/vectorize.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/helloworld/helloworld.rb b/examples/helloworld/helloworld.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/image_processing/adaptive_thresholding.rb b/examples/image_processing/adaptive_thresholding.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/image_processing/binary_thresholding.rb b/examples/image_processing/binary_thresholding.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/image_processing/brain_segmentation.rb b/examples/image_processing/brain_segmentation.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/image_processing/edge.rb b/examples/image_processing/edge.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/image_processing/filters.rb b/examples/image_processing/filters.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/image_processing/image_demo.rb b/examples/image_processing/image_demo.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/image_processing/image_editing.rb b/examples/image_processing/image_editing.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/image_processing/morphing.rb b/examples/image_processing/morphing.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/image_processing/optical_flow.rb b/examples/image_processing/optical_flow.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/image_processing/pyramids.rb b/examples/image_processing/pyramids.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/lin_algebra/cholesky.rb b/examples/lin_algebra/cholesky.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/lin_algebra/lu.rb b/examples/lin_algebra/lu.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/lin_algebra/qr.rb b/examples/lin_algebra/qr.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/lin_algebra/svd.rb b/examples/lin_algebra/svd.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/machine_learning/bagging.rb b/examples/machine_learning/bagging.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/machine_learning/deep_belief_net.rb b/examples/machine_learning/deep_belief_net.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/machine_learning/geneticalgorithm.rb b/examples/machine_learning/geneticalgorithm.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/machine_learning/kmeans.rb b/examples/machine_learning/kmeans.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/machine_learning/knn.rb b/examples/machine_learning/knn.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/machine_learning/logistic_regression.rb b/examples/machine_learning/logistic_regression.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/machine_learning/naive_bayes.rb b/examples/machine_learning/naive_bayes.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/machine_learning/neural_network.rb b/examples/machine_learning/neural_network.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/machine_learning/perceptron.rb b/examples/machine_learning/perceptron.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/machine_learning/rbm.rb b/examples/machine_learning/rbm.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/machine_learning/softmax_regression.rb b/examples/machine_learning/softmax_regression.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/pde/swe.rb b/examples/pde/swe.rb
new file mode 100644
index 0000000..e69de29
diff --git a/examples/unified/basic.rb b/examples/unified/basic.rb
new file mode 100644
index 0000000..e69de29
diff --git a/ext/mri/arrayfire.c b/ext/mri/arrayfire.c
index 159102e..cc6508a 100644
--- a/ext/mri/arrayfire.c
+++ b/ext/mri/arrayfire.c
@@ -1,68 +1,680 @@
-// #include "ruby.h"
-
-#include "arrayfire.h"
#include
#include
-#include "ruby_arrayfire.h"
-
VALUE ArrayFire = Qnil;
VALUE Af_Array = Qnil;
-VALUE Device = Qnil;
+VALUE Algorithm = Qnil;
+VALUE Backend = Qnil;
VALUE Blas = Qnil;
+VALUE Cuda = Qnil;
+VALUE Data = Qnil;
+VALUE Device = Qnil;
+VALUE Index = Qnil;
VALUE Lapack = Qnil;
+VALUE OpenCL = Qnil;
+VALUE Random = Qnil;
+VALUE Sparse = Qnil;
+VALUE Statistics = Qnil;
+VALUE Util = Qnil;
+extern "C++" {
+ VALUE cNMatrix;
+}
-typedef struct AF_STRUCT
-{
- size_t dimension; // Method of storage (csc, dense, etc).
- size_t array;
-}afstruct;
+// prototypes
+void Init_arrayfire();
+void arf_handle_exception(af_err error_code);
+const char* get_backend_name(af_backend backend);
+const char* get_cl_device_name(afcl_device_type device);
+const char* get_cl_platform_name(afcl_platform platform);
+const char* get_random_engine_name(af_random_engine_type engine);
+
+af_backend arf_backend_type_from_rbsymbol(VALUE sym);
+af_dtype arf_dtype_from_rbsymbol(VALUE sym);
+af_mat_prop arf_mat_type_from_rbsymbol(VALUE sym);
+af_moment_type arf_moment_type_from_rbsymbol(VALUE sym);
+af_norm_type arf_norm_type_from_rbsymbol(VALUE sym);
+af_random_engine_type arf_randome_engine_type_from_rbsymbol(VALUE sym);
+af_source arf_source_from_rbsymbol(VALUE sym);
-// prototypes
-// void Init_arrayfire();
-static VALUE test1(VALUE self);
-// VALUE method_arf_init(VALUE self, VALUE val);
static VALUE arf_init(int argc, VALUE* argv, VALUE self);
static VALUE arf_alloc(VALUE klass);
static void arf_free(afstruct* af);
-static VALUE dimension(VALUE self);
-static VALUE array(VALUE self);
-static VALUE get_info(VALUE self);
+static VALUE arf_engine_alloc(VALUE klass);
+static void arf_engine_free(afrandomenginestruct* afrandomengine);
+
+// Af_Array
+static VALUE arf_create_array(int argc, VALUE* argv);
+static VALUE arf_create_handle(int argc, VALUE* argv);
+static VALUE arf_copy_array(VALUE self);
+static VALUE arf_write_array(VALUE self);
+static VALUE arf_get_data_ptr(VALUE self);
+static VALUE arf_release_array(VALUE self);
+static VALUE arf_retain_array(VALUE self);
+static VALUE arf_get_data_ref_count(VALUE self);
+static VALUE arf_eval(VALUE self);
+static VALUE arf_eval_multiple(VALUE self);
+static VALUE arf_set_manual_eval_flag(VALUE self, VALUE flag);
+static VALUE arf_get_manual_eval_flag(VALUE self);
+static VALUE arf_get_elements(VALUE self);
+static VALUE arf_get_type(VALUE self);
+static VALUE arf_get_dims(VALUE self);
+static VALUE arf_get_numdims(VALUE self);
+static VALUE arf_is_empty(VALUE self);
+static VALUE arf_is_scalar(VALUE self);
+static VALUE arf_is_row(VALUE self);
+static VALUE arf_is_column(VALUE self);
+static VALUE arf_is_vector(VALUE self);
+static VALUE arf_is_complex(VALUE self);
+static VALUE arf_is_real(VALUE self);
+static VALUE arf_is_double(VALUE self);
+static VALUE arf_is_single(VALUE self);
+static VALUE arf_is_realfloating(VALUE self);
+static VALUE arf_is_floating(VALUE self);
+static VALUE arf_is_integer(VALUE self);
+static VALUE arf_is_bool(VALUE self);
+static VALUE arf_is_sparse(VALUE self);
+
+static VALUE arf_to_string(VALUE self);
+
+// Algorithm
+static VALUE arf_sum(VALUE self, VALUE array_val, VALUE dim_val);
+static VALUE arf_sum_nan(VALUE self, VALUE array_val, VALUE dim_val, VALUE nan_val);
+static VALUE arf_product(VALUE self, VALUE array_val, VALUE dim_val);
+static VALUE arf_product_nan(VALUE self, VALUE array_val, VALUE dim_val, VALUE nan_val);
+static VALUE arf_min(VALUE self, VALUE array_val, VALUE dim_val);
+static VALUE arf_max(VALUE self, VALUE array_val, VALUE dim_val);
+static VALUE arf_all_true(VALUE self, VALUE array_val, VALUE dim_val);
+static VALUE arf_any_true(VALUE self, VALUE array_val, VALUE dim_val);
+static VALUE arf_count(VALUE self, VALUE array_val, VALUE dim_val);
+static VALUE arf_sum_all(VALUE self, VALUE array_val);
+static VALUE arf_sum_nan_all(VALUE self, VALUE array_val, VALUE nan_val);
+static VALUE arf_product_all(VALUE self, VALUE array_val);
+static VALUE arf_product_nan_all(VALUE self, VALUE array_val, VALUE nan_val);
+static VALUE arf_min_all(VALUE self, VALUE array_val);
+static VALUE arf_max_all(VALUE self, VALUE array_val);
+static VALUE arf_all_true_all(VALUE self, VALUE array_val);
+static VALUE arf_any_true_all(VALUE self, VALUE array_val);
+static VALUE arf_count_all(VALUE self, VALUE array_val);
+static VALUE arf_imin(VALUE self, VALUE array_val, VALUE dim_val);
+static VALUE arf_imax(VALUE self, VALUE array_val, VALUE dim_val);
+static VALUE arf_imin_all(VALUE self, VALUE array_val);
+static VALUE arf_imax_all(VALUE self, VALUE array_val);
+static VALUE arf_accum(VALUE self, VALUE array_val, VALUE dim_val);
+static VALUE arf_scan(VALUE self);
+static VALUE arf_scan_by_key(VALUE self);
+static VALUE arf_where(VALUE self);
+static VALUE arf_diff1(VALUE self);
+static VALUE arf_diff2(VALUE self);
+static VALUE arf_sort(VALUE self);
+static VALUE arf_sort_index(VALUE self);
+static VALUE arf_sort_by_key(VALUE self);
+static VALUE arf_set_unique(VALUE self);
+static VALUE arf_set_union(VALUE self);
+static VALUE arf_set_intersect(VALUE self);
+
+// Backend
+static VALUE arf_get_backend_count(VALUE self);
+static VALUE arf_get_available_backends(VALUE self);
+static VALUE arf_get_backend_id(VALUE self, VALUE array_val);
+static VALUE arf_get_active_backend(VALUE self);
+static VALUE arf_get_backend_device_id(VALUE self, VALUE array_val);
+static VALUE arf_set_backend(VALUE self, VALUE backend_val);
+
+// BLAS
+static VALUE arf_matmul(VALUE self, VALUE left_val, VALUE right_val, VALUE left_prop_val, VALUE right_prop_val);
+static VALUE arf_dot(VALUE self, VALUE left_val, VALUE right_val, VALUE left_prop_val, VALUE right_prop_val);
+static VALUE arf_transpose(VALUE self, VALUE input);
+static VALUE arf_transpose_inplace(VALUE self, VALUE input);
+
+// CUDA
+static VALUE arf_get_stream(VALUE self, VALUE id);
+static VALUE arf_get_native_id(VALUE self, VALUE cuda_device_id);
+static VALUE arf_set_native_id(VALUE self, VALUE native_id);
+
+// Device
+static VALUE arf_info(VALUE self);
+static VALUE arf_init2(VALUE self);
+static VALUE arf_info_string(VALUE self, VALUE bool_val);
+static VALUE arf_device_info(VALUE self, VALUE name_val, VALUE platform_val, VALUE toolkit_val, VALUE compute_val);
+static VALUE arf_get_device_count(VALUE self);
+static VALUE arf_get_dbl_support(VALUE self, VALUE device);
+static VALUE arf_set_device(VALUE self, VALUE device);
+static VALUE arf_get_device(VALUE self);
+static VALUE arf_sync(VALUE self, VALUE device_val);
+static VALUE arf_alloc_device(VALUE self);
+static VALUE arf_free_device(VALUE self);
+static VALUE arf_alloc_pinned(VALUE self);
+static VALUE arf_free_pinned(VALUE self);
+static VALUE arf_alloc_host(VALUE self);
+static VALUE arf_free_host(VALUE self);
+static VALUE arf_device_array(VALUE self);
+static VALUE arf_device_mem_info(VALUE self);
+static VALUE arf_print_mem_info(VALUE self, VALUE msg_val, VALUE device_id_val);
+static void arf_device_gc(VALUE self);
+static VALUE arf_set_mem_step_size(VALUE self, VALUE step_bytes);
+static VALUE arf_get_mem_step_size(VALUE self);
+static VALUE arf_lock_device_ptr(VALUE self, VALUE array_val);
+static VALUE arf_unlock_device_ptr(VALUE self, VALUE array_val);
+static VALUE arf_lock_array(VALUE self, VALUE array_val);
+static VALUE arf_unlock_array(VALUE self, VALUE array_val);
+static VALUE arf_is_locked_array(VALUE self, VALUE array_val);
+static VALUE arf_get_device_ptr(VALUE self);
+
+// OpenCL
+static VALUE arf_get_context(VALUE self);
+static VALUE arf_get_queue(VALUE self);
+static VALUE arf_get_device_id(VALUE self);
+static VALUE arf_set_device_id(VALUE self);
+static VALUE arf_add_device_context(VALUE self);
+static VALUE arf_set_device_context(VALUE self);
+static VALUE arf_delete_device_context(VALUE self);
+static VALUE arf_get_device_type(VALUE self);
+static VALUE arf_get_platform(VALUE self);
+
+// Data
+static VALUE arf_constant(int argc, VALUE* argv);
+static VALUE arf_constant_complex(VALUE self);
+static VALUE arf_constant_long(int argc, VALUE* argv);
+static VALUE arf_constant_ulong(int argc, VALUE* argv);
+static VALUE arf_range(int argc, VALUE* argv);
+static VALUE arf_iota(VALUE self);
+static VALUE arf_identity(int argc, VALUE* argv);
+static VALUE arf_diag_create(VALUE self, VALUE array_val, VALUE num_val);
+static VALUE arf_diag_extract(VALUE self, VALUE array_val, VALUE num_val);
+static VALUE arf_join(VALUE self, VALUE dim_val, VALUE first_array_val, VALUE second_array_val);
+static VALUE arf_join_many(VALUE self);
+static VALUE arf_tile(VALUE self, VALUE array_val, VALUE x_val, VALUE y_val, VALUE z_val, VALUE w_val);
+static VALUE arf_reorder(VALUE self, VALUE array_val, VALUE x_val, VALUE y_val, VALUE z_val, VALUE w_val);
+static VALUE arf_shift(VALUE self, VALUE array_val, VALUE x_val, VALUE y_val, VALUE z_val, VALUE w_val);
+static VALUE arf_moddims(VALUE self);
+static VALUE arf_flat(VALUE self, VALUE array_val);
+static VALUE arf_flip(VALUE self, VALUE array_val, VALUE dim_val);
+static VALUE arf_lower(VALUE self, VALUE array_val, VALUE dim_val);
+static VALUE arf_upper(VALUE self, VALUE array_val, VALUE dim_val);
+static VALUE arf_select(VALUE self, VALUE array_cond_val, VALUE array_a_val, VALUE array_b_val);
+static VALUE arf_select_scalar_r(VALUE self, VALUE array_cond_val, VALUE array_a_val, VALUE b_val);
+static VALUE arf_select_scalar_l(VALUE self, VALUE array_cond_val, VALUE a_val, VALUE array_b_val);
+static VALUE arf_replace(VALUE self, VALUE array_input_val, VALUE array_cond_val, VALUE array_b_val);
+static VALUE arf_replace_scalar(VALUE self, VALUE array_input_val, VALUE array_cond_val, VALUE b_val);
+
+// Index
+static VALUE arf_index(VALUE self);
+static VALUE arf_lookup(VALUE self);
+static VALUE arf_assign_seq(VALUE self);
+static VALUE arf_index_gen(VALUE self);
+static VALUE arf_assign_gen(VALUE self);
+static VALUE arf_create_indexers(VALUE self);
+static VALUE arf_set_array_indexer(VALUE self);
+static VALUE arf_set_seq_indexer(VALUE self);
+static VALUE arf_set_seq_param_indexer(VALUE self);
+static VALUE arf_release_indexers(VALUE self);
+
+// LAPACK
+static VALUE arf_svd_func(VALUE self, VALUE u_val, VALUE s_val, VALUE vt_val, VALUE val);
+static VALUE arf_svd_inplace_func(VALUE self, VALUE val);
+static VALUE arf_lu_func(VALUE self, VALUE lower_val, VALUE upper_val, VALUE pivot_val, VALUE val);
+static VALUE arf_lu_inplace_func(VALUE self);
+static VALUE arf_qr_func(VALUE self, VALUE q_val, VALUE r_val, VALUE tau_val, VALUE val);
+static VALUE arf_qr_inplace_func(VALUE self);
+static VALUE arf_cholesky_func(VALUE self, VALUE output_val, VALUE val, VALUE is_upper_val);
+static VALUE arf_cholesky_inplace_func(VALUE self);
+static VALUE arf_solve(VALUE self, VALUE lhs_val, VALUE rhs_val);
+static VALUE arf_solve_lu(VALUE self, VALUE lhs_val, VALUE rhs_val, VALUE piv_val);
+static VALUE arf_inverse(VALUE self, VALUE val);
+static VALUE arf_rank(VALUE self, VALUE val);
+static VALUE arf_det(VALUE self, VALUE val);
+static VALUE arf_norm(VALUE self, VALUE val);
+static VALUE arf_is_lapack_available(VALUE self);
+
+// Random
+static VALUE arf_create_random_engine(VALUE self, VALUE type_val, VALUE seed_val);
+static VALUE arf_retain_random_engine(VALUE self, VALUE engine_val);
+static VALUE arf_random_engine_set_type(VALUE self, VALUE engine_val, VALUE type_val);
+static VALUE arf_random_engine_get_type(VALUE self, VALUE engine_val);
+static VALUE arf_random_uniform(VALUE self, VALUE ndims_val, VALUE dim_val, VALUE engine_val);
+static VALUE arf_random_normal(VALUE self, VALUE ndims_val, VALUE dim_val, VALUE engine_val);
+static VALUE arf_random_engine_set_seed(VALUE self, VALUE engine_val ,VALUE seed_val);
+static VALUE arf_get_default_random_engine(VALUE self);
+static VALUE arf_set_default_random_engine_type(VALUE self, VALUE type_val);
+static VALUE arf_random_engine_get_seed(VALUE self, VALUE engine_val);
+static VALUE arf_release_random_engine(VALUE self, VALUE engine_val);
+static VALUE arf_randu(VALUE self, VALUE ndims_val, VALUE dim_val);
+static VALUE arf_randn(VALUE self, VALUE ndims_val, VALUE dim_val);
+static VALUE arf_set_seed(VALUE self, VALUE seed);
+static VALUE arf_get_seed(VALUE self);
+
+// Sparse
+static VALUE arf_create_sparse_array(VALUE self, VALUE shape_array, VALUE values_array, VALUE rowIdx_val, VALUE colIdx_val, VALUE stype_val);
+static VALUE arf_create_sparse_array_from_ptr(VALUE self);
+static VALUE arf_create_sparse_array_from_dense(VALUE self, VALUE dense_val, VALUE stype_val);
+static VALUE arf_sparse_convert_to(VALUE self, VALUE input_val, VALUE dest_storage_val);
+static VALUE arf_sparse_to_dense(VALUE self, VALUE sparse_array);
+static VALUE arf_sparse_get_info_func(VALUE self, VALUE values_val, VALUE rowIdx_val, VALUE colIdx_val, VALUE input_val);
+static VALUE arf_sparse_get_values(VALUE self, VALUE input_val);
+static VALUE arf_sparse_get_row_idx(VALUE self, VALUE input_val);
+static VALUE arf_sparse_get_col_idx(VALUE self, VALUE input_val);
+static VALUE arf_sparse_get_nnz(VALUE self, VALUE input_val);
+static VALUE arf_sparse_get_storage(VALUE self, VALUE input_val);
+
+// Statistics
+static VALUE arf_mean(VALUE self, VALUE array_val, VALUE dim_val);
+static VALUE arf_mean_weighted(VALUE self, VALUE array_val, VALUE weighted_array_val, VALUE dim_val);
+static VALUE arf_var(VALUE self, VALUE array_val, VALUE is_biased, VALUE dim_val);
+static VALUE arf_var_weighted(VALUE self, VALUE array_val, VALUE weighted_array_val, VALUE dim_val);
+static VALUE arf_stdev(VALUE self, VALUE array_val, VALUE dim_val);
+static VALUE arf_cov(VALUE self, VALUE first_array_val, VALUE second_array_val, VALUE is_biased);
+static VALUE arf_median(VALUE self, VALUE array_val, VALUE dim_val);
+static VALUE arf_mean_all(VALUE self, VALUE array_val);
+static VALUE arf_mean_all_weighted(VALUE self, VALUE array_val, VALUE weighted_array_val);
+static VALUE arf_var_all(VALUE self, VALUE array_val, VALUE is_biased);
+static VALUE arf_var_all_weighted(VALUE self, VALUE array_val, VALUE weighted_array_val);
+static VALUE arf_stdev_all(VALUE self, VALUE array_val);
+static VALUE arf_median_all(VALUE self, VALUE array_val);
+static VALUE arf_corrcoef(VALUE self, VALUE first_array_val, VALUE second_array_val);
+
+// Util
+static VALUE arf_print_array(VALUE self, VALUE input_val);
+static VALUE arf_print_array_gen(VALUE self);
+static VALUE arf_save_array(VALUE self, VALUE key_val, VALUE array_val, VALUE fn_val, VALUE append);
+static VALUE arf_read_array_index(VALUE self);
+static VALUE arf_read_array_key(VALUE self);
+static VALUE arf_read_array_key_check(VALUE self);
+static VALUE arf_array_to_string(VALUE self, VALUE exp_val, VALUE array_val, VALUE precision, VALUE transpose);
+static VALUE arf_example_function(VALUE self);
+static VALUE arf_get_version(VALUE self);
+static VALUE arf_get_revision(VALUE self);
+static VALUE arf_get_size_of(VALUE self, VALUE dtype_val);
+
+#define DECL_ELEMENTWISE_RUBY_ACCESSOR(name) static VALUE arf_ew_##name(VALUE left_val, VALUE right_val);
+#define DECL_UNARY_RUBY_ACCESSOR(name) static VALUE arf_unary_##name(VALUE self);
+
+DECL_ELEMENTWISE_RUBY_ACCESSOR(add)
+DECL_ELEMENTWISE_RUBY_ACCESSOR(subtract)
+DECL_ELEMENTWISE_RUBY_ACCESSOR(multiply)
+DECL_ELEMENTWISE_RUBY_ACCESSOR(divide)
+
+DECL_ELEMENTWISE_RUBY_ACCESSOR(eqeq)
+DECL_ELEMENTWISE_RUBY_ACCESSOR(neq)
+DECL_ELEMENTWISE_RUBY_ACCESSOR(leq)
+DECL_ELEMENTWISE_RUBY_ACCESSOR(geq)
+DECL_ELEMENTWISE_RUBY_ACCESSOR(lt)
+DECL_ELEMENTWISE_RUBY_ACCESSOR(gt)
+
+DECL_UNARY_RUBY_ACCESSOR(sin)
+DECL_UNARY_RUBY_ACCESSOR(cos)
+DECL_UNARY_RUBY_ACCESSOR(tan)
+DECL_UNARY_RUBY_ACCESSOR(asin)
+DECL_UNARY_RUBY_ACCESSOR(acos)
+DECL_UNARY_RUBY_ACCESSOR(atan)
+DECL_UNARY_RUBY_ACCESSOR(sinh)
+DECL_UNARY_RUBY_ACCESSOR(cosh)
+DECL_UNARY_RUBY_ACCESSOR(tanh)
+DECL_UNARY_RUBY_ACCESSOR(asinh)
+DECL_UNARY_RUBY_ACCESSOR(acosh)
+DECL_UNARY_RUBY_ACCESSOR(atanh)
+DECL_UNARY_RUBY_ACCESSOR(exp)
+DECL_UNARY_RUBY_ACCESSOR(log2)
+DECL_UNARY_RUBY_ACCESSOR(log1p)
+DECL_UNARY_RUBY_ACCESSOR(log10)
+DECL_UNARY_RUBY_ACCESSOR(sqrt)
+DECL_UNARY_RUBY_ACCESSOR(erf)
+DECL_UNARY_RUBY_ACCESSOR(erfc)
+DECL_UNARY_RUBY_ACCESSOR(cbrt)
+DECL_UNARY_RUBY_ACCESSOR(lgamma)
+DECL_UNARY_RUBY_ACCESSOR(tgamma)
+DECL_UNARY_RUBY_ACCESSOR(floor)
+DECL_UNARY_RUBY_ACCESSOR(ceil)
+
+/*
+ * Macro defines an element-wise accessor function for some operation.
+ *
+ * This is only responsible for the Ruby accessor! You still have to write the actual functions, obviously.
+ */
+
+static VALUE arf_eqeq(VALUE left_val, VALUE right_val);
+static VALUE arf_eqeq_approx(VALUE left_val, VALUE right_val);
+
+// Interfaces
+
+static VALUE arf_af_array_to_nmatrix(VALUE self);
+extern VALUE arf_nmatrix_to_af_array_method(VALUE nmatrix);
+afstruct* arf_nmatrix_to_af_array(VALUE nm);
void Init_arrayfire() {
ArrayFire = rb_define_module("ArrayFire");
- rb_define_method(ArrayFire, "test1", (METHOD)test1, 0);
Af_Array = rb_define_class_under(ArrayFire, "Af_Array", rb_cObject);
rb_define_alloc_func(Af_Array, arf_alloc);
rb_define_method(Af_Array, "initialize", (METHOD)arf_init, -1);
- rb_define_method(Af_Array, "dimension", (METHOD)dimension, 0);
- rb_define_method(Af_Array, "array", (METHOD)array, 0);
+ rb_define_singleton_method(Af_Array, "create_array", (METHOD)arf_create_array, -1);
+ rb_define_singleton_method(Af_Array, "create_handle", (METHOD)arf_create_handle, -1);
+ rb_define_method(Af_Array, "copy_array", (METHOD)arf_copy_array, 0);
+ rb_define_method(Af_Array, "write_array", (METHOD)arf_write_array, 0);
+ rb_define_method(Af_Array, "get_data_ptr", (METHOD)arf_get_data_ptr, 0);
+ rb_define_method(Af_Array, "release_array", (METHOD)arf_release_array, 0);
+ rb_define_method(Af_Array, "retain_array", (METHOD)arf_retain_array, 0);
+ rb_define_method(Af_Array, "get_data_ref_count", (METHOD)arf_get_data_ref_count, 0);
+ rb_define_method(Af_Array, "eval", (METHOD)arf_eval, 0);
+ rb_define_method(Af_Array, "eval_multiple", (METHOD)arf_eval_multiple, 0);
+ rb_define_singleton_method(Af_Array, "set_manual_eval_flag", (METHOD)arf_set_manual_eval_flag, 1);
+ rb_define_singleton_method(Af_Array, "get_manual_eval_flag", (METHOD)arf_get_manual_eval_flag, 0);
+ rb_define_method(Af_Array, "get_elements", (METHOD)arf_get_elements, 0);
+ rb_define_method(Af_Array, "get_type", (METHOD)arf_get_type, 0);
+ rb_define_method(Af_Array, "get_dims", (METHOD)arf_get_dims, 0);
+ rb_define_method(Af_Array, "get_numdims", (METHOD)arf_get_numdims, 0);
+ rb_define_method(Af_Array, "is_empty", (METHOD)arf_is_empty, 0);
+ rb_define_method(Af_Array, "is_scalar", (METHOD)arf_is_scalar, 0);
+ rb_define_method(Af_Array, "is_row", (METHOD)arf_is_row, 0);
+ rb_define_method(Af_Array, "is_column", (METHOD)arf_is_column, 0);
+ rb_define_method(Af_Array, "is_vector", (METHOD)arf_is_vector, 0);
+ rb_define_method(Af_Array, "is_complex", (METHOD)arf_is_complex, 0);
+ rb_define_method(Af_Array, "is_real", (METHOD)arf_is_real, 0);
+ rb_define_method(Af_Array, "is_double", (METHOD)arf_is_double, 0);
+ rb_define_method(Af_Array, "is_single", (METHOD)arf_is_single, 0);
+ rb_define_method(Af_Array, "is_realfloating", (METHOD)arf_is_realfloating, 0);
+ rb_define_method(Af_Array, "is_floating", (METHOD)arf_is_floating, 0);
+ rb_define_method(Af_Array, "is_integer", (METHOD)arf_is_integer, 0);
+ rb_define_method(Af_Array, "is_bool", (METHOD)arf_is_bool, 0);
+ rb_define_method(Af_Array, "is_sparse", (METHOD)arf_is_sparse, 0);
+
+ rb_define_method(Af_Array, "to_s", (METHOD)arf_to_string, 0);
+
+ rb_define_alias(Af_Array, "ndims", "get_numdims");
+ rb_define_alias(Af_Array, "dims", "get_dims");
+ rb_define_alias(Af_Array, "to_cpu", "get_data_ptr");
+ rb_define_alias(Af_Array, "elements", "get_data_ptr");
+
+ rb_define_method(Af_Array, "+",(METHOD)arf_ew_add,1);
+ rb_define_method(Af_Array, "-",(METHOD)arf_ew_subtract,1);
+ rb_define_method(Af_Array, "*",(METHOD)arf_ew_multiply,1);
+ rb_define_method(Af_Array, "/",(METHOD)arf_ew_divide,1);
+ rb_define_method(Af_Array, "==",(METHOD)arf_eqeq,1);
+ rb_define_method(Af_Array, "approx_equal",(METHOD)arf_eqeq_approx,1);
+
+ rb_define_method(Af_Array, "=~",(METHOD)arf_ew_eqeq,1);
+ rb_define_method(Af_Array, "!~", (METHOD)arf_ew_neq, 1);
+ rb_define_method(Af_Array, "<=", (METHOD)arf_ew_leq, 1);
+ rb_define_method(Af_Array, ">=", (METHOD)arf_ew_geq, 1);
+ rb_define_method(Af_Array, "<", (METHOD)arf_ew_lt, 1);
+ rb_define_method(Af_Array, ">", (METHOD)arf_ew_gt, 1);
+
+ rb_define_method(Af_Array, "sin", (METHOD)arf_unary_sin, 0);
+ rb_define_method(Af_Array, "cos", (METHOD)arf_unary_cos, 0);
+ rb_define_method(Af_Array, "tan", (METHOD)arf_unary_tan, 0);
+ rb_define_method(Af_Array, "asin", (METHOD)arf_unary_asin, 0);
+ rb_define_method(Af_Array, "acos", (METHOD)arf_unary_acos, 0);
+ rb_define_method(Af_Array, "atan", (METHOD)arf_unary_atan, 0);
+ rb_define_method(Af_Array, "sinh", (METHOD)arf_unary_sinh, 0);
+ rb_define_method(Af_Array, "cosh", (METHOD)arf_unary_cosh, 0);
+ rb_define_method(Af_Array, "tanh", (METHOD)arf_unary_tanh, 0);
+ rb_define_method(Af_Array, "asinh", (METHOD)arf_unary_asinh, 0);
+ rb_define_method(Af_Array, "acosh", (METHOD)arf_unary_acosh, 0);
+ rb_define_method(Af_Array, "atanh", (METHOD)arf_unary_atanh, 0);
+ rb_define_method(Af_Array, "exp", (METHOD)arf_unary_exp, 0);
+ rb_define_method(Af_Array, "log2", (METHOD)arf_unary_log2, 0);
+ rb_define_method(Af_Array, "log1p", (METHOD)arf_unary_log1p, 0);
+ rb_define_method(Af_Array, "log10", (METHOD)arf_unary_log10, 0);
+ rb_define_method(Af_Array, "sqrt", (METHOD)arf_unary_sqrt, 0);
+ rb_define_method(Af_Array, "erf", (METHOD)arf_unary_erf, 0);
+ rb_define_method(Af_Array, "erfc", (METHOD)arf_unary_erfc, 0);
+ rb_define_method(Af_Array, "cbrt", (METHOD)arf_unary_cbrt, 0);
+ rb_define_method(Af_Array, "lgamma", (METHOD)arf_unary_lgamma, 0);
+ rb_define_method(Af_Array, "tgamma", (METHOD)arf_unary_tgamma, 0);
+ rb_define_method(Af_Array, "floor", (METHOD)arf_unary_floor, 0);
+ rb_define_method(Af_Array, "ceil", (METHOD)arf_unary_ceil, 0);
+
+ rb_define_method(Af_Array, "to_nmatrix", (METHOD)arf_af_array_to_nmatrix, 0);
+
+ cNMatrix = rb_define_class("NMatrix", rb_cObject);
+ rb_define_method(cNMatrix, "to_af_array", (METHOD)arf_nmatrix_to_af_array_method, 0);
+
+ Algorithm = rb_define_class_under(ArrayFire, "Algorithm", rb_cObject);
+ rb_define_singleton_method(Algorithm, "sum", (METHOD)arf_sum, 2);
+ rb_define_singleton_method(Algorithm, "sum_nan", (METHOD)arf_sum_nan, 3);
+ rb_define_singleton_method(Algorithm, "product", (METHOD)arf_product, 2);
+ rb_define_singleton_method(Algorithm, "product_nan", (METHOD)arf_product_nan, 3);
+ rb_define_singleton_method(Algorithm, "min", (METHOD)arf_min, 2);
+ rb_define_singleton_method(Algorithm, "max", (METHOD)arf_max, 2);
+ rb_define_singleton_method(Algorithm, "all_true", (METHOD)arf_all_true, 2);
+ rb_define_singleton_method(Algorithm, "any_true", (METHOD)arf_any_true, 2);
+ rb_define_singleton_method(Algorithm, "count", (METHOD)arf_count, 2);
+ rb_define_singleton_method(Algorithm, "sum_all", (METHOD)arf_sum_all, 1);
+ rb_define_singleton_method(Algorithm, "sum_nan_all", (METHOD)arf_sum_nan_all, 2);
+ rb_define_singleton_method(Algorithm, "product_all", (METHOD)arf_product_all, 1);
+ rb_define_singleton_method(Algorithm, "product_nan_all", (METHOD)arf_product_nan_all, 2);
+ rb_define_singleton_method(Algorithm, "min_all", (METHOD)arf_min_all, 1);
+ rb_define_singleton_method(Algorithm, "max_all", (METHOD)arf_max_all, 1);
+ rb_define_singleton_method(Algorithm, "all_true_all", (METHOD)arf_all_true_all, 1);
+ rb_define_singleton_method(Algorithm, "any_true_all", (METHOD)arf_any_true_all, 1);
+ rb_define_singleton_method(Algorithm, "count_all", (METHOD)arf_count_all, 1);
+ rb_define_singleton_method(Algorithm, "imin", (METHOD)arf_imin, 0);
+ rb_define_singleton_method(Algorithm, "imax", (METHOD)arf_imax, 0);
+ rb_define_singleton_method(Algorithm, "imin_all", (METHOD)arf_imin_all, 0);
+ rb_define_singleton_method(Algorithm, "imax_all", (METHOD)arf_imax_all, 0);
+ rb_define_singleton_method(Algorithm, "accum", (METHOD)arf_accum, 0);
+ rb_define_singleton_method(Algorithm, "scan", (METHOD)arf_scan, 0);
+ rb_define_singleton_method(Algorithm, "scan_by_key", (METHOD)arf_scan_by_key, 0);
+ rb_define_singleton_method(Algorithm, "where", (METHOD)arf_where, 0);
+ rb_define_singleton_method(Algorithm, "diff1", (METHOD)arf_diff1, 0);
+ rb_define_singleton_method(Algorithm, "diff2", (METHOD)arf_diff2, 0);
+ rb_define_singleton_method(Algorithm, "sort", (METHOD)arf_sort, 0);
+ rb_define_singleton_method(Algorithm, "sort_index", (METHOD)arf_sort_index, 0);
+ rb_define_singleton_method(Algorithm, "sort_by_key", (METHOD)arf_sort_by_key, 0);
+ rb_define_singleton_method(Algorithm, "set_unique", (METHOD)arf_set_unique, 0);
+ rb_define_singleton_method(Algorithm, "set_union", (METHOD)arf_set_union, 0);
+ rb_define_singleton_method(Algorithm, "set_intersect", (METHOD)arf_set_intersect, 0);
+
+ Backend = rb_define_class_under(ArrayFire, "Backend", rb_cObject);
+ rb_define_singleton_method(Backend, "get_backend_count", (METHOD)arf_get_backend_count, 0);
+ rb_define_singleton_method(Backend, "get_available_backends", (METHOD)arf_get_available_backends, 0);
+ rb_define_singleton_method(Backend, "get_backend_id", (METHOD)arf_get_backend_id, 1);
+ rb_define_singleton_method(Backend, "get_active_backend", (METHOD)arf_get_active_backend, 0);
+ rb_define_singleton_method(Backend, "get_device_id", (METHOD)arf_get_backend_device_id, 1);
+ rb_define_singleton_method(Backend, "set_backend", (METHOD)arf_set_backend, 1);
Device = rb_define_class_under(ArrayFire, "Device", rb_cObject);
- rb_define_method(Device, "getInfo", (METHOD)get_info, 0);
+ rb_define_singleton_method(Device, "info", (METHOD)arf_info, 0);
+ rb_define_singleton_method(Device, "init", (METHOD)arf_init2, 0);
+ rb_define_singleton_method(Device, "info_string", (METHOD)arf_info_string, 1);
+ rb_define_singleton_method(Device, "device_info_func", (METHOD)arf_device_info, 4);
+ rb_define_singleton_method(Device, "get_device_count", (METHOD)arf_get_device_count, 0);
+ rb_define_singleton_method(Device, "get_dbl_support", (METHOD)arf_get_dbl_support, 1);
+ rb_define_singleton_method(Device, "set_device", (METHOD)arf_set_device, 1);
+ rb_define_singleton_method(Device, "get_device", (METHOD)arf_get_device, 0);
+ rb_define_singleton_method(Device, "sync", (METHOD)arf_sync, 1);
+ rb_define_singleton_method(Device, "alloc_device", (METHOD)arf_alloc_device, 0);
+ rb_define_singleton_method(Device, "free_device", (METHOD)arf_free_device, 0);
+ rb_define_singleton_method(Device, "alloc_pinned", (METHOD)arf_alloc_pinned, 0);
+ rb_define_singleton_method(Device, "free_pinned", (METHOD)arf_free_pinned, 0);
+ rb_define_singleton_method(Device, "alloc_host", (METHOD)arf_alloc_host, 0);
+ rb_define_singleton_method(Device, "free_host", (METHOD)arf_free_host, 0);
+ rb_define_singleton_method(Device, "device_array", (METHOD)arf_device_array, 0);
+ rb_define_singleton_method(Device, "device_mem_info", (METHOD)arf_device_mem_info, 0);
+ rb_define_singleton_method(Device, "print_mem_info", (METHOD)arf_print_mem_info, 2);
+ rb_define_singleton_method(Device, "device_gc", (METHOD)arf_device_gc, 0);
+ rb_define_singleton_method(Device, "set_mem_step_size", (METHOD)arf_set_mem_step_size, 1);
+ rb_define_singleton_method(Device, "get_mem_step_size", (METHOD)arf_get_mem_step_size, 0);
+ rb_define_singleton_method(Device, "lock_device_ptr", (METHOD)arf_lock_device_ptr, 1);
+ rb_define_singleton_method(Device, "unlock_device_ptr", (METHOD)arf_unlock_device_ptr, 1);
+ rb_define_singleton_method(Device, "lock_array", (METHOD)arf_lock_array, 1);
+ rb_define_singleton_method(Device, "unlock_array", (METHOD)arf_unlock_array, 1);
+ rb_define_singleton_method(Device, "is_locked_array", (METHOD)arf_is_locked_array, 1);
+ rb_define_singleton_method(Device, "get_device_ptr", (METHOD)arf_get_device_ptr, 0);
Blas = rb_define_class_under(ArrayFire, "BLAS", rb_cObject);
+ rb_define_singleton_method(Blas, "matmul", (METHOD)arf_matmul, 4);
+ rb_define_singleton_method(Blas, "dot", (METHOD)arf_dot, 4);
+ rb_define_singleton_method(Blas, "transpose", (METHOD)arf_transpose, 1);
+ rb_define_singleton_method(Blas, "transpose_inplace", (METHOD)arf_transpose_inplace, 1);
+
+ Cuda = rb_define_class_under(ArrayFire, "CUDA", rb_cObject);
+ rb_define_singleton_method(Cuda, "get_stream", (METHOD)arf_get_stream, 1);
+ rb_define_singleton_method(Cuda, "get_native_id", (METHOD)arf_get_native_id, 1);
+ rb_define_singleton_method(Cuda, "set_native_id", (METHOD)arf_set_native_id, 1);
+
+ Index = rb_define_class_under(ArrayFire, "Index", rb_cObject);
+ rb_define_singleton_method(Index, "index", (METHOD)arf_index, 0);
+ rb_define_singleton_method(Index, "lookup", (METHOD)arf_lookup, 0);
+ rb_define_singleton_method(Index, "assign_seq", (METHOD)arf_assign_seq, 0);
+ rb_define_singleton_method(Index, "index_gen", (METHOD)arf_index_gen, 0);
+ rb_define_singleton_method(Index, "assign_gen", (METHOD)arf_assign_gen, 0);
+ rb_define_singleton_method(Index, "create_indexers", (METHOD)arf_create_indexers, 0);
+ rb_define_singleton_method(Index, "set_array_indexer", (METHOD)arf_set_array_indexer, 0);
+ rb_define_singleton_method(Index, "set_seq_indexer", (METHOD)arf_set_seq_indexer, 0);
+ rb_define_singleton_method(Index, "set_seq_param_indexer", (METHOD)arf_set_seq_param_indexer, 0);
+ rb_define_singleton_method(Index, "release_indexers", (METHOD)arf_release_indexers, 0);
+
+ OpenCL = rb_define_class_under(ArrayFire, "OpenCL", rb_cObject);
+ rb_define_singleton_method(OpenCL, "get_context", (METHOD)arf_get_context, 0);
+ rb_define_singleton_method(OpenCL, "get_queue", (METHOD)arf_get_queue, 0);
+ rb_define_singleton_method(OpenCL, "get_device_id", (METHOD)arf_get_device_id, 0);
+ rb_define_singleton_method(OpenCL, "set_device_id", (METHOD)arf_set_device_id, 0);
+ rb_define_singleton_method(OpenCL, "add_device_context", (METHOD)arf_add_device_context, 0);
+ rb_define_singleton_method(OpenCL, "set_device_context", (METHOD)arf_set_device_context, 0);
+ rb_define_singleton_method(OpenCL, "delete_device_context", (METHOD)arf_delete_device_context, 0);
+ rb_define_singleton_method(OpenCL, "get_device_type", (METHOD)arf_get_device_type, 0);
+ rb_define_singleton_method(OpenCL, "get_platform", (METHOD)arf_get_platform, 0);
+
+ Data = rb_define_class_under(ArrayFire, "Data", rb_cObject);
+ rb_define_singleton_method(Data, "constant", (METHOD)arf_constant, -1);
+ rb_define_singleton_method(Data, "constant_complex", (METHOD)arf_constant_complex, 0);
+ rb_define_singleton_method(Data, "constant_long", (METHOD)arf_constant_long, -1);
+ rb_define_singleton_method(Data, "constant_ulong", (METHOD)arf_constant_ulong, -1);
+ rb_define_singleton_method(Data, "range", (METHOD)arf_range, -1);
+ rb_define_singleton_method(Data, "iota", (METHOD)arf_iota, 0);
+ rb_define_singleton_method(Data, "identity", (METHOD)arf_identity, -1);
+ rb_define_singleton_method(Data, "diag_create", (METHOD)arf_diag_create, 2);
+ rb_define_singleton_method(Data, "diag_extract", (METHOD)arf_diag_extract, 2);
+ rb_define_singleton_method(Data, "join", (METHOD)arf_join, 3);
+ rb_define_singleton_method(Data, "join_many", (METHOD)arf_join_many, 0);
+ rb_define_singleton_method(Data, "tile", (METHOD)arf_tile, 5);
+ rb_define_singleton_method(Data, "reorder", (METHOD)arf_reorder, 5);
+ rb_define_singleton_method(Data, "shift", (METHOD)arf_shift, 5);
+ rb_define_singleton_method(Data, "moddims", (METHOD)arf_moddims, 0);
+ rb_define_singleton_method(Data, "flat", (METHOD)arf_flat, 1);
+ rb_define_singleton_method(Data, "flip", (METHOD)arf_flip, 2);
+ rb_define_singleton_method(Data, "lower", (METHOD)arf_lower, 2);
+ rb_define_singleton_method(Data, "upper", (METHOD)arf_upper, 2);
+ rb_define_singleton_method(Data, "select", (METHOD)arf_select, 3);
+ rb_define_singleton_method(Data, "select_scalar_r", (METHOD)arf_select_scalar_r, 3);
+ rb_define_singleton_method(Data, "select_scalar_l", (METHOD)arf_select_scalar_l, 3);
+ rb_define_singleton_method(Data, "replace", (METHOD)arf_replace, 3);
+ rb_define_singleton_method(Data, "replace_scalar", (METHOD)arf_replace_scalar, 3);
Lapack = rb_define_class_under(ArrayFire, "LAPACK", rb_cObject);
-}
+ rb_define_singleton_method(Lapack, "svd_func", (METHOD)arf_svd_func, 4);
+ rb_define_singleton_method(Lapack, "svd_inplace_func", (METHOD)arf_svd_inplace_func, 1);
+ rb_define_singleton_method(Lapack, "lu_func", (METHOD)arf_lu_func, 4);
+ rb_define_singleton_method(Lapack, "lu_inplace_func", (METHOD)arf_lu_inplace_func, 1);
+ rb_define_singleton_method(Lapack, "qr_func", (METHOD)arf_qr_func, 4);
+ rb_define_singleton_method(Lapack, "qr_inplace_func", (METHOD)arf_qr_inplace_func, 1);
+ rb_define_singleton_method(Lapack, "cholesky_func", (METHOD)arf_cholesky_func, 3);
+ rb_define_singleton_method(Lapack, "cholesky_inplace_func", (METHOD)arf_cholesky_inplace_func, 1);
+ rb_define_singleton_method(Lapack, "solve", (METHOD)arf_solve, 2);
+ rb_define_singleton_method(Lapack, "solve_lu", (METHOD)arf_solve_lu, 3);
+ rb_define_singleton_method(Lapack, "inverse", (METHOD)arf_inverse, 1);
+ rb_define_singleton_method(Lapack, "rank", (METHOD)arf_rank, 1);
+ rb_define_singleton_method(Lapack, "det", (METHOD)arf_det, 1);
+ rb_define_singleton_method(Lapack, "norm", (METHOD)arf_norm, 1);
+ rb_define_singleton_method(Lapack, "is_lapack_available", (METHOD)arf_is_lapack_available, 0);
+
+ Random = rb_define_class_under(ArrayFire, "Random", rb_cObject);
+ rb_define_alloc_func(Random, arf_engine_alloc);
+ rb_define_singleton_method(Random, "create_random_engine", (METHOD)arf_create_random_engine, 2);
+ rb_define_singleton_method(Random, "retain_random_engine", (METHOD)arf_retain_random_engine, 1);
+ rb_define_singleton_method(Random, "random_engine_set_type", (METHOD)arf_random_engine_set_type, 2);
+ rb_define_singleton_method(Random, "random_engine_get_type", (METHOD)arf_random_engine_get_type, 1);
+ rb_define_singleton_method(Random, "random_uniform", (METHOD)arf_random_uniform, 3);
+ rb_define_singleton_method(Random, "random_normal", (METHOD)arf_random_normal, 3);
+ rb_define_singleton_method(Random, "random_engine_set_seed", (METHOD)arf_random_engine_set_seed, 2);
+ rb_define_singleton_method(Random, "get_default_random_engine", (METHOD)arf_get_default_random_engine, 0);
+ rb_define_singleton_method(Random, "set_default_random_engine_type", (METHOD)arf_set_default_random_engine_type, 1);
+ rb_define_singleton_method(Random, "random_engine_get_seed", (METHOD)arf_random_engine_get_seed, 1);
+ rb_define_singleton_method(Random, "release_random_engine", (METHOD)arf_release_random_engine, 1);
+ rb_define_singleton_method(Random, "randu", (METHOD)arf_randu, 2);
+ rb_define_singleton_method(Random, "randn", (METHOD)arf_randn, 2);
+ rb_define_singleton_method(Random, "set_seed", (METHOD)arf_set_seed, 1);
+ rb_define_singleton_method(Random, "get_seed", (METHOD)arf_get_seed, 0);
+
+ Sparse = rb_define_class_under(ArrayFire, "Sparse", rb_cObject);
+ rb_define_singleton_method(Sparse, "create_sparse_array", (METHOD)arf_create_sparse_array, 5);
+ rb_define_singleton_method(Sparse, "create_sparse_array_from_ptr", (METHOD)arf_create_sparse_array_from_ptr, 0);
+ rb_define_singleton_method(Sparse, "create_sparse_array_from_dense", (METHOD)arf_create_sparse_array_from_dense, 2);
+ rb_define_singleton_method(Sparse, "sparse_convert_to", (METHOD)arf_sparse_convert_to, 2);
+ rb_define_singleton_method(Sparse, "sparse_to_dense", (METHOD)arf_sparse_to_dense, 1);
+ rb_define_singleton_method(Sparse, "sparse_get_info_func", (METHOD)arf_sparse_get_info_func, 4);
+ rb_define_singleton_method(Sparse, "sparse_get_values", (METHOD)arf_sparse_get_values, 1);
+ rb_define_singleton_method(Sparse, "sparse_get_row_idx", (METHOD)arf_sparse_get_row_idx, 1);
+ rb_define_singleton_method(Sparse, "sparse_get_col_idx", (METHOD)arf_sparse_get_col_idx, 1);
+ rb_define_singleton_method(Sparse, "sparse_get_nnz", (METHOD)arf_sparse_get_nnz, 1);
+ rb_define_singleton_method(Sparse, "sparse_get_storage", (METHOD)arf_sparse_get_storage, 1);
+
+ Statistics = rb_define_class_under(ArrayFire, "Statistics", rb_cObject);
+ rb_define_singleton_method(Statistics, "mean", (METHOD)arf_mean, 2);
+ rb_define_singleton_method(Statistics, "mean_weighted", (METHOD)arf_mean_weighted, 3);
+ rb_define_singleton_method(Statistics, "var", (METHOD)arf_var, 3);
+ rb_define_singleton_method(Statistics, "var_weighted", (METHOD)arf_var_weighted, 3);
+ rb_define_singleton_method(Statistics, "stdev", (METHOD)arf_stdev, 2);
+ rb_define_singleton_method(Statistics, "cov", (METHOD)arf_cov, 3);
+ rb_define_singleton_method(Statistics, "median", (METHOD)arf_median, 2);
+ rb_define_singleton_method(Statistics, "mean_all", (METHOD)arf_mean_all, 1);
+ rb_define_singleton_method(Statistics, "mean_all_weighted", (METHOD)arf_mean_all_weighted, 2);
+ rb_define_singleton_method(Statistics, "var_all", (METHOD)arf_var_all, 2);
+ rb_define_singleton_method(Statistics, "var_all_weighted", (METHOD)arf_var_all_weighted, 2);
+ rb_define_singleton_method(Statistics, "stdev_all", (METHOD)arf_stdev_all, 1);
+ rb_define_singleton_method(Statistics, "median_all", (METHOD)arf_median_all, 1);
+ rb_define_singleton_method(Statistics, "corrcoef", (METHOD)arf_corrcoef, 2);
+
+ Util = rb_define_class_under(ArrayFire, "Util", rb_cObject);
+ rb_define_singleton_method(Util, "print_array", (METHOD)arf_print_array, 1);
+ rb_define_singleton_method(Util, "print_array_gen", (METHOD)arf_print_array_gen, 0);
+ rb_define_singleton_method(Util, "save_array", (METHOD)arf_save_array, 4);
+ rb_define_singleton_method(Util, "read_array_index", (METHOD)arf_read_array_index, 0);
+ rb_define_singleton_method(Util, "read_array_key", (METHOD)arf_read_array_key, 0);
+ rb_define_singleton_method(Util, "read_array_key_check", (METHOD)arf_read_array_key_check, 0);
+ rb_define_singleton_method(Util, "array_to_string", (METHOD)arf_array_to_string, 4);
+ rb_define_singleton_method(Util, "example_function", (METHOD)arf_example_function, 0);
+ rb_define_singleton_method(Util, "get_version", (METHOD)arf_get_version, 0);
+ rb_define_singleton_method(Util, "get_revision", (METHOD)arf_get_revision, 0);
+ rb_define_singleton_method(Util, "get_size_of", (METHOD)arf_get_size_of, 1);
-VALUE test1(VALUE self) {
- VALUE x;
- x = rb_str_new_cstr("Hello, world!");
- return x;
}
+/*
+ * call-seq:
+ * new(dimesnsion) -> Af_Array
+ * new(dims, dimesnsion, elements, data_type) -> Af_Array
+ *
+ * Create a new Af_Array.
+ *
+ */
+
VALUE arf_init(int argc, VALUE* argv, VALUE self)
{
-
afstruct* afarray;
Data_Get_Struct(self, afstruct, afarray);
- afarray->dimension = argv[0];
- afarray->array = argv[1];
+ if(argc > 0){
+ af_dtype dtype = (argc == 4) ? arf_dtype_from_rbsymbol(argv[3]) : f64;
+
+ dim_t ndims = (dim_t)FIX2LONG(argv[0]);
+ dim_t* dimensions = ALLOC_N(dim_t, ndims);
+ dim_t count = 1;
+ for (dim_t index = 0; index < ndims; index++) {
+ dimensions[index] = (dim_t)FIX2LONG(RARRAY_AREF(argv[1], index));
+ count *= dimensions[index];
+ }
+ double* host_array = ALLOC_N(double, count);
+ for (dim_t index = 0; index < count; index++) {
+ host_array[index] = (double)NUM2DBL(RARRAY_AREF(argv[2], index));
+ }
+ af_err flag = af_create_array(&afarray->carray, host_array, ndims, dimensions, dtype);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(afarray->carray);
+ }
return self;
}
@@ -75,35 +687,108 @@ static VALUE arf_alloc(VALUE klass)
return Data_Wrap_Struct(klass, NULL, arf_free, af);
}
+static VALUE arf_engine_alloc(VALUE klass)
+{
+ /* allocate */
+ afrandomenginestruct* afrandomengine = ALLOC(afrandomenginestruct);
+ /* wrap */
+ return Data_Wrap_Struct(klass, NULL, arf_engine_free, afrandomengine);
+}
static void arf_free(afstruct* af)
{
- free(af);
+ xfree(af);
}
-static VALUE dimension(VALUE self)
+static void arf_engine_free(afrandomenginestruct* afrandomengine)
{
- afstruct * af;
+ xfree(afrandomengine);
+}
+
- Data_Get_Struct(self, afstruct, af);
+static VALUE arf_to_string(VALUE self){
+ char* output;
+ afstruct* input;
- return af->dimension;
+ Data_Get_Struct(self, afstruct, input);
+ const char* exp = "";
+ af_array_to_string(&output, exp, input->carray, 3, false);
+
+ return rb_str_new_cstr(output);
}
-static VALUE array(VALUE self)
-{
- afstruct * af;
+static VALUE arf_eqeq(VALUE left_val, VALUE right_val) {
+ afstruct* left;
+ afstruct* right;
+ afstruct* result = ALLOC(afstruct);
+ Data_Get_Struct(left_val, afstruct, left);
+ Data_Get_Struct(right_val, afstruct, right);
+ af_eq(&result->carray, left->carray, right->carray, true);
- Data_Get_Struct(self, afstruct, af);
+ dim_t count;
+ af_get_elements(&count, result->carray);
+ bool* data = ALLOC_N(bool, count);
+ af_err flag = af_get_data_ptr(data, result->carray);
- return af->array;
+ if(flag != AF_SUCCESS){
+ rb_raise(rb_eArgError, "Something went wrong!");
+ }
+
+ for (dim_t index = 0; index < count; index++){
+ if(!data[index]){
+ return Qfalse;
+ }
+ }
+ return Qtrue;
}
-static VALUE get_info(VALUE self)
-{
- VALUE x;
- af_info();
- arf::matmul_benchmark();
- return x;
+static VALUE arf_eqeq_approx(VALUE left_val, VALUE right_val) {
+
+ afstruct* left;
+ afstruct* right;
+
+ dim_t left_count;
+ dim_t right_count;
+
+ Data_Get_Struct(left_val, afstruct, left);
+ Data_Get_Struct(right_val, afstruct, right);
+
+ af_get_elements(&left_count, left->carray);
+ af_get_elements(&right_count, right->carray);
+
+ if(left_count != right_count){return Qfalse;}
+
+ double* left_arr = ALLOC_N(double, left_count);
+ af_get_data_ptr(left_arr, left->carray);
+
+ double* right_arr = ALLOC_N(double, left_count);
+ af_get_data_ptr(right_arr, right->carray);
+
+ for (dim_t index = 0; index < left_count; index++){
+ double diff = left_arr[index] - right_arr[index];
+ if(diff < 0){diff *= -1;}
+ if(diff > 1e-3){
+ return Qfalse;
+ }
+ }
+ return Qtrue;
}
+#include "cmodules/array.c"
+#include "cmodules/algorithm.c"
+#include "cmodules/arith.c"
+#include "cmodules/backend.c"
+#include "cmodules/blas.c"
+#include "cmodules/cuda.c"
+#include "cmodules/data.c"
+#include "cmodules/defines.c"
+#include "cmodules/device.c"
+#include "cmodules/index.c"
+#include "cmodules/lapack.c"
+#include "cmodules/opencl.c"
+#include "cmodules/random.c"
+#include "cmodules/sparse.c"
+#include "cmodules/statistics.c"
+#include "cmodules/util.c"
+
+#include "interfaces/nmatrix.c"
diff --git a/ext/mri/cmodules/algorithm.c b/ext/mri/cmodules/algorithm.c
new file mode 100644
index 0000000..73b783d
--- /dev/null
+++ b/ext/mri/cmodules/algorithm.c
@@ -0,0 +1,286 @@
+static VALUE arf_sum(VALUE self, VALUE array_val, VALUE dim_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_sum(&output->carray, input->carray, FIX2INT(dim_val));
+
+ return Data_Wrap_Struct(CLASS_OF(array_val), NULL, arf_free, output);
+}
+
+static VALUE arf_sum_nan(VALUE self, VALUE array_val, VALUE dim_val, VALUE nan_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_sum_nan(&output->carray, input->carray, FIX2INT(dim_val), NUM2DBL(nan_val));
+
+ return Data_Wrap_Struct(CLASS_OF(array_val), NULL, arf_free, output);
+}
+
+static VALUE arf_product(VALUE self, VALUE array_val, VALUE dim_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_product(&output->carray, input->carray, FIX2INT(dim_val));
+
+ return Data_Wrap_Struct(CLASS_OF(array_val), NULL, arf_free, output);
+}
+
+static VALUE arf_product_nan(VALUE self, VALUE array_val, VALUE dim_val, VALUE nan_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_product_nan(&output->carray, input->carray, FIX2INT(dim_val), NUM2DBL(nan_val));
+
+ return Data_Wrap_Struct(CLASS_OF(array_val), NULL, arf_free, output);
+}
+
+static VALUE arf_min(VALUE self, VALUE array_val, VALUE dim_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_min(&output->carray, input->carray, FIX2INT(dim_val));
+
+ return Data_Wrap_Struct(CLASS_OF(array_val), NULL, arf_free, output);
+}
+
+static VALUE arf_max(VALUE self, VALUE array_val, VALUE dim_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_max(&output->carray, input->carray, FIX2INT(dim_val));
+
+ return Data_Wrap_Struct(CLASS_OF(array_val), NULL, arf_free, output);
+}
+
+static VALUE arf_all_true(VALUE self, VALUE array_val, VALUE dim_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_all_true(&output->carray, input->carray, FIX2INT(dim_val));
+
+ return Data_Wrap_Struct(CLASS_OF(array_val), NULL, arf_free, output);
+}
+
+static VALUE arf_any_true(VALUE self, VALUE array_val, VALUE dim_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_any_true(&output->carray, input->carray, FIX2INT(dim_val));
+
+ return Data_Wrap_Struct(CLASS_OF(array_val), NULL, arf_free, output);
+}
+
+static VALUE arf_count(VALUE self, VALUE array_val, VALUE dim_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_count(&output->carray, input->carray, FIX2INT(dim_val));
+
+ return Data_Wrap_Struct(CLASS_OF(array_val), NULL, arf_free, output);
+}
+
+static VALUE arf_sum_all(VALUE self, VALUE array_val){
+ afstruct* input;
+ double real_part, imag_part;
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_sum_all(&real_part, &imag_part, input->carray);
+
+ return DBL2NUM(real_part);
+}
+
+static VALUE arf_sum_nan_all(VALUE self, VALUE array_val, VALUE nan_val){
+ afstruct* input;
+ double real_part, imag_part;
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_sum_nan_all(&real_part, &imag_part, input->carray, NUM2DBL(nan_val));
+
+ return DBL2NUM(real_part);
+}
+
+static VALUE arf_product_all(VALUE self, VALUE array_val){
+ afstruct* input;
+ double real_part, imag_part;
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_product_all(&real_part, &imag_part, input->carray);
+
+ return DBL2NUM(real_part);
+}
+
+static VALUE arf_product_nan_all(VALUE self, VALUE array_val, VALUE nan_val){
+ afstruct* input;
+ double real_part, imag_part;
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_product_nan_all(&real_part, &imag_part, input->carray, NUM2DBL(nan_val));
+
+ return DBL2NUM(real_part);
+}
+
+static VALUE arf_min_all(VALUE self, VALUE array_val){
+ afstruct* input;
+ double real_part, imag_part;
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_min_all(&real_part, &imag_part, input->carray);
+
+ return DBL2NUM(real_part);
+}
+
+static VALUE arf_max_all(VALUE self, VALUE array_val){
+ afstruct* input;
+ double real_part, imag_part;
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_max_all(&real_part, &imag_part, input->carray);
+
+ return DBL2NUM(real_part);
+}
+
+static VALUE arf_all_true_all(VALUE self, VALUE array_val){
+ afstruct* input;
+ double real_part, imag_part;
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_all_true_all(&real_part, &imag_part, input->carray);
+
+ return DBL2NUM(real_part);
+}
+
+static VALUE arf_any_true_all(VALUE self, VALUE array_val){
+ afstruct* input;
+ double real_part, imag_part;
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_any_true_all(&real_part, &imag_part, input->carray);
+
+ return DBL2NUM(real_part);
+}
+
+static VALUE arf_count_all(VALUE self, VALUE array_val){
+ afstruct* input;
+ double real_part, imag_part;
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_count_all(&real_part, &imag_part, input->carray);
+
+ return DBL2NUM(real_part);
+}
+
+static VALUE arf_imin(VALUE self, VALUE array_val, VALUE dim_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+ afstruct* idx = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_imin(&output->carray, &idx->carray, input->carray, FIX2INT(dim_val));
+ return Data_Wrap_Struct(CLASS_OF(array_val), NULL, arf_free, output);
+}
+
+static VALUE arf_imax(VALUE self, VALUE array_val, VALUE dim_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+ afstruct* idx = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_imax(&output->carray, &idx->carray, input->carray, FIX2INT(dim_val));
+ return Data_Wrap_Struct(CLASS_OF(array_val), NULL, arf_free, output);
+}
+
+static VALUE arf_imin_all(VALUE self, VALUE array_val){
+ afstruct* input;
+ double real_part, imag_part;
+ uint idx;
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_imin_all(&real_part, &imag_part, &idx, input->carray);
+ return DBL2NUM(real_part);
+}
+
+static VALUE arf_imax_all(VALUE self, VALUE array_val){
+ afstruct* input;
+ double real_part, imag_part;
+ uint idx;
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_imax_all(&real_part, &imag_part, &idx, input->carray);
+ return DBL2NUM(real_part);
+}
+
+static VALUE arf_accum(VALUE self, VALUE array_val, VALUE dim_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_accum(&output->carray, input->carray, FIX2INT(dim_val));
+
+ return Data_Wrap_Struct(CLASS_OF(array_val), NULL, arf_free, output);
+}
+
+static VALUE arf_scan(VALUE self){
+ return Qnil;
+}
+static VALUE arf_scan_by_key(VALUE self){
+ return Qnil;
+}
+static VALUE arf_where(VALUE self){
+ return Qnil;
+}
+static VALUE arf_diff1(VALUE self){
+ return Qnil;
+}
+static VALUE arf_diff2(VALUE self){
+ return Qnil;
+}
+static VALUE arf_sort(VALUE self){
+ return Qnil;
+}
+static VALUE arf_sort_index(VALUE self){
+ return Qnil;
+}
+static VALUE arf_sort_by_key(VALUE self){
+ return Qnil;
+}
+static VALUE arf_set_unique(VALUE self){
+ return Qnil;
+}
+static VALUE arf_set_union(VALUE self){
+ return Qnil;
+}
+static VALUE arf_set_intersect(VALUE self){
+ return Qnil;
+}
\ No newline at end of file
diff --git a/ext/mri/cmodules/arith.c b/ext/mri/cmodules/arith.c
new file mode 100644
index 0000000..fdbea23
--- /dev/null
+++ b/ext/mri/cmodules/arith.c
@@ -0,0 +1,60 @@
+#define DEF_ELEMENTWISE_RUBY_ACCESSOR(name, oper) \
+static VALUE arf_ew_##name(VALUE left_val, VALUE right_val) { \
+ afstruct* left; \
+ afstruct* right; \
+ afstruct* result = ALLOC(afstruct); \
+ Data_Get_Struct(left_val, afstruct, left); \
+ Data_Get_Struct(right_val, afstruct, right); \
+ af_err flag = af_##oper(&result->carray, left->carray, right->carray, true); \
+ if (flag != AF_SUCCESS) arf_handle_exception(flag); \
+ af_print_array(result->carray); \
+ return Data_Wrap_Struct(CLASS_OF(left_val), NULL, arf_free, result); \
+}
+
+#define DEF_UNARY_RUBY_ACCESSOR(oper, name) \
+static VALUE arf_unary_##name(VALUE self) { \
+ afstruct* obj; \
+ afstruct* result = ALLOC(afstruct); \
+ Data_Get_Struct(self, afstruct, obj); \
+ af_err flag = af_##oper(&result->carray, obj->carray); \
+ if (flag != AF_SUCCESS) arf_handle_exception(flag); \
+ af_print_array(result->carray); \
+ return Data_Wrap_Struct(CLASS_OF(self), NULL, arf_free, result); \
+}
+
+DEF_ELEMENTWISE_RUBY_ACCESSOR(add, add)
+DEF_ELEMENTWISE_RUBY_ACCESSOR(subtract, sub)
+DEF_ELEMENTWISE_RUBY_ACCESSOR(multiply, mul)
+DEF_ELEMENTWISE_RUBY_ACCESSOR(divide, div)
+
+DEF_ELEMENTWISE_RUBY_ACCESSOR(eqeq, eq)
+DEF_ELEMENTWISE_RUBY_ACCESSOR(neq, neq)
+DEF_ELEMENTWISE_RUBY_ACCESSOR(leq, le)
+DEF_ELEMENTWISE_RUBY_ACCESSOR(geq, ge)
+DEF_ELEMENTWISE_RUBY_ACCESSOR(lt, lt)
+DEF_ELEMENTWISE_RUBY_ACCESSOR(gt, gt)
+
+DEF_UNARY_RUBY_ACCESSOR(sin, sin)
+DEF_UNARY_RUBY_ACCESSOR(cos, cos)
+DEF_UNARY_RUBY_ACCESSOR(tan, tan)
+DEF_UNARY_RUBY_ACCESSOR(asin, asin)
+DEF_UNARY_RUBY_ACCESSOR(acos, acos)
+DEF_UNARY_RUBY_ACCESSOR(atan, atan)
+DEF_UNARY_RUBY_ACCESSOR(sinh, sinh)
+DEF_UNARY_RUBY_ACCESSOR(cosh, cosh)
+DEF_UNARY_RUBY_ACCESSOR(tanh, tanh)
+DEF_UNARY_RUBY_ACCESSOR(asinh, asinh)
+DEF_UNARY_RUBY_ACCESSOR(acosh, acosh)
+DEF_UNARY_RUBY_ACCESSOR(atanh, atanh)
+DEF_UNARY_RUBY_ACCESSOR(exp, exp)
+DEF_UNARY_RUBY_ACCESSOR(log2, log2)
+DEF_UNARY_RUBY_ACCESSOR(log1p, log1p)
+DEF_UNARY_RUBY_ACCESSOR(log10, log10)
+DEF_UNARY_RUBY_ACCESSOR(sqrt, sqrt)
+DEF_UNARY_RUBY_ACCESSOR(erf, erf)
+DEF_UNARY_RUBY_ACCESSOR(erfc, erfc)
+DEF_UNARY_RUBY_ACCESSOR(cbrt, cbrt)
+DEF_UNARY_RUBY_ACCESSOR(lgamma, lgamma)
+DEF_UNARY_RUBY_ACCESSOR(tgamma, tgamma)
+DEF_UNARY_RUBY_ACCESSOR(floor, floor)
+DEF_UNARY_RUBY_ACCESSOR(ceil, ceil)
diff --git a/ext/mri/cmodules/array.c b/ext/mri/cmodules/array.c
new file mode 100644
index 0000000..cd5e4d9
--- /dev/null
+++ b/ext/mri/cmodules/array.c
@@ -0,0 +1,377 @@
+static VALUE arf_create_array(int argc, VALUE* argv){
+ afstruct* afarray = ALLOC(afstruct);
+ dim_t ndims = (dim_t)FIX2LONG(argv[0]);
+ dim_t* dimensions = ALLOC_N(dim_t, ndims);
+ dim_t count = 1;
+ for (dim_t index = 0; index < ndims; index++) {
+ dimensions[index] = (dim_t)FIX2LONG(RARRAY_AREF(argv[1], index));
+ count *= dimensions[index];
+ }
+ double* host_array = ALLOC_N(double, count);;
+ for (dim_t index = 0; index < count; index++) {
+ host_array[index] = (double)NUM2DBL(RARRAY_AREF(argv[2], index));
+ }
+
+ af_err flag = af_create_array(&afarray->carray, host_array, ndims, dimensions, f32);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(afarray->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, afarray);
+}
+
+static VALUE arf_create_handle(int argc, VALUE* argv){
+ afstruct* afarray = ALLOC(afstruct);
+ dim_t ndims = (dim_t)FIX2LONG(argv[0]);
+ dim_t* dimensions = ALLOC_N(dim_t, ndims);
+ dim_t count = 1;
+ for (dim_t index = 0; index < ndims; index++) {
+ dimensions[index] = (dim_t)FIX2LONG(RARRAY_AREF(argv[1], index));
+ count *= dimensions[index];
+ }
+ double* host_array = ALLOC_N(double, count);
+ for (dim_t index = 0; index < count; index++) {
+ host_array[index] = (double)NUM2DBL(RARRAY_AREF(argv[2], index));
+ }
+
+ af_err flag = af_create_handle(&afarray->carray, ndims, dimensions, f32);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(afarray->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, afarray);
+}
+
+static VALUE arf_copy_array(VALUE self){
+ afstruct* array_val;
+ afstruct* result = ALLOC(afstruct);
+
+ Data_Get_Struct(self, afstruct, array_val);
+
+ af_err flag = af_copy_array(&result->carray, array_val->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(CLASS_OF(self), NULL, arf_free, result);
+}
+
+static VALUE arf_write_array(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_get_data_ptr(VALUE self){
+ afstruct* input;
+ dim_t count;
+
+ Data_Get_Struct(self, afstruct, input);
+
+ af_err flag = af_get_elements(&count, input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ double* data = ALLOC_N(double, count);
+
+ flag = af_get_data_ptr(data, input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ VALUE* array = ALLOC_N(VALUE, count);
+ for (dim_t index = 0; index < count; index++){
+ array[index] = DBL2NUM(data[index]);
+ }
+
+ return rb_ary_new4(count, array);
+}
+
+static VALUE arf_release_array(VALUE self){
+ afstruct* input;
+ Data_Get_Struct(self, afstruct, input);
+ af_err flag = af_release_array(input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return Qtrue;
+}
+
+static VALUE arf_retain_array(VALUE self){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+ Data_Get_Struct(self, afstruct, input);
+ af_err flag = af_retain_array(&output->carray, input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return Data_Wrap_Struct(CLASS_OF(self), NULL, arf_free, output);
+}
+
+static VALUE arf_get_data_ref_count(VALUE self){
+ afstruct* input;
+ int use_count;
+ Data_Get_Struct(self, afstruct, input);
+ af_err flag = af_get_data_ref_count(&use_count, input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return INT2NUM(use_count);
+}
+
+static VALUE arf_eval(VALUE self){
+ afstruct* input;
+ Data_Get_Struct(self, afstruct, input);
+ af_err flag = af_eval(input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return Qtrue;
+}
+
+static VALUE arf_eval_multiple(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_set_manual_eval_flag(VALUE self, VALUE flag){
+ af_err code = af_set_manual_eval_flag(RTEST(flag));
+ if (code != AF_SUCCESS) arf_handle_exception(code);
+ return Qtrue;
+}
+
+static VALUE arf_get_manual_eval_flag(VALUE self){
+ bool flag;
+ af_err code = af_get_manual_eval_flag(&flag);
+ if (code != AF_SUCCESS) arf_handle_exception(code);
+ return flag ? Qtrue : Qfalse;
+}
+
+static VALUE arf_get_elements(VALUE self){
+ afstruct* input;
+
+ dim_t elems;
+
+ Data_Get_Struct(self, afstruct, input);
+
+ af_err flag = af_get_elements(&elems, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return ULONG2NUM(elems);
+}
+
+static VALUE arf_get_type(VALUE self){
+ afstruct* input;
+ af_dtype type;
+
+ Data_Get_Struct(self, afstruct, input);
+
+ af_err flag = af_get_type(&type, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Qnil;
+}
+
+static VALUE arf_get_dims(VALUE self){
+ afstruct* input;
+ Data_Get_Struct(self, afstruct, input);
+
+ uint ndims;
+
+ af_err flag = af_get_numdims(&ndims, input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ dim_t* dims = ALLOC_N(dim_t, ndims);
+
+ flag = af_get_dims(&dims[0], &dims[1], &dims[2], &dims[3], input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ VALUE* array = ALLOC_N(VALUE, ndims);
+ for (dim_t index = 0; index < ndims; index++){
+ array[index] = UINT2NUM(dims[index]);
+ }
+
+ return rb_ary_new4(ndims, array);
+}
+
+static VALUE arf_get_numdims(VALUE self){
+ afstruct* input;
+ uint result;
+
+ Data_Get_Struct(self, afstruct, input);
+
+ af_err flag = af_get_numdims(&result, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return UINT2NUM(result);
+}
+
+static VALUE arf_is_empty(VALUE self){
+ afstruct* input;
+ bool result;
+
+ Data_Get_Struct(self, afstruct, input);
+
+ af_err flag = af_is_empty(&result, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return result ? Qtrue : Qfalse;
+}
+
+static VALUE arf_is_scalar(VALUE self){
+ afstruct* input;
+ bool result;
+
+ Data_Get_Struct(self, afstruct, input);
+
+ af_err flag = af_is_scalar(&result, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return result ? Qtrue : Qfalse;
+}
+
+static VALUE arf_is_row(VALUE self){
+ afstruct* input;
+ bool result;
+
+ Data_Get_Struct(self, afstruct, input);
+
+ af_err flag = af_is_row(&result, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return result ? Qtrue : Qfalse;
+}
+
+static VALUE arf_is_column(VALUE self){
+ afstruct* input;
+ bool result;
+
+ Data_Get_Struct(self, afstruct, input);
+
+ af_err flag = af_is_column(&result, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return result ? Qtrue : Qfalse;
+}
+
+static VALUE arf_is_vector(VALUE self){
+ afstruct* input;
+ bool result;
+
+ Data_Get_Struct(self, afstruct, input);
+
+ af_err flag = af_is_vector(&result, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return result ? Qtrue : Qfalse;
+}
+
+static VALUE arf_is_complex(VALUE self){
+ afstruct* input;
+ bool result;
+
+ Data_Get_Struct(self, afstruct, input);
+
+ af_err flag = af_is_complex(&result, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return result ? Qtrue : Qfalse;
+}
+
+static VALUE arf_is_real(VALUE self){
+ afstruct* input;
+ bool result;
+
+ Data_Get_Struct(self, afstruct, input);
+
+ af_err flag = af_is_real(&result, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return result ? Qtrue : Qfalse;
+}
+
+static VALUE arf_is_double(VALUE self){
+ afstruct* input;
+ bool result;
+
+ Data_Get_Struct(self, afstruct, input);
+
+ af_err flag = af_is_double(&result, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return result ? Qtrue : Qfalse;
+}
+
+static VALUE arf_is_single(VALUE self){
+ afstruct* input;
+ bool result;
+
+ Data_Get_Struct(self, afstruct, input);
+
+ af_err flag = af_is_single(&result, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return result ? Qtrue : Qfalse;
+}
+
+static VALUE arf_is_realfloating(VALUE self){
+ afstruct* input;
+ bool result;
+
+ Data_Get_Struct(self, afstruct, input);
+
+ af_err flag = af_is_realfloating(&result, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return result ? Qtrue : Qfalse;
+}
+
+static VALUE arf_is_floating(VALUE self){
+ afstruct* input;
+ bool result;
+
+ Data_Get_Struct(self, afstruct, input);
+
+ af_err flag = af_is_floating(&result, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return result ? Qtrue : Qfalse;
+}
+
+static VALUE arf_is_integer(VALUE self){
+ afstruct* input;
+ bool result;
+
+ Data_Get_Struct(self, afstruct, input);
+
+ af_err flag = af_is_integer(&result, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return result ? Qtrue : Qfalse;
+}
+
+static VALUE arf_is_bool(VALUE self){
+ afstruct* input;
+ bool result;
+
+ Data_Get_Struct(self, afstruct, input);
+
+ af_err flag = af_is_bool(&result, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return result ? Qtrue : Qfalse;
+}
+
+static VALUE arf_is_sparse(VALUE self){
+ afstruct* input;
+ bool result = false;
+
+ Data_Get_Struct(self, afstruct, input);
+
+ //FIXME
+ af_err flag = af_is_bool(&result, input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return result ? Qtrue : Qfalse;
+}
diff --git a/ext/mri/cmodules/backend.c b/ext/mri/cmodules/backend.c
new file mode 100644
index 0000000..443f371
--- /dev/null
+++ b/ext/mri/cmodules/backend.c
@@ -0,0 +1,65 @@
+static VALUE arf_get_backend_count(VALUE self){
+ uint num_backends;
+
+ af_err flag = af_get_backend_count(&num_backends);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return UINT2NUM(num_backends);
+}
+
+// int backends = af::getAvailableBackends();
+// bool cpu = backends & AF_BACKEND_CPU;
+// bool cuda = backends & AF_BACKEND_CUDA;
+// bool opencl = backends & AF_BACKEND_OPENCL;
+
+static VALUE arf_get_available_backends(VALUE self){
+ int backends;
+
+ af_err flag = af_get_available_backends(&backends);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return INT2NUM(backends);
+}
+
+static VALUE arf_get_backend_id(VALUE self, VALUE array_val){
+ afstruct* input;
+ Data_Get_Struct(array_val, afstruct, input);
+ af_backend backend;
+
+ af_err flag = af_get_backend_id (&backend, input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ const char* backend_name = get_backend_name(backend);
+ return rb_str_new_cstr(backend_name);
+}
+
+static VALUE arf_get_active_backend(VALUE self){
+ af_backend backend;
+
+ af_err flag = af_get_active_backend(&backend);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ const char* backend_name = get_backend_name(backend);
+ return rb_str_new_cstr(backend_name);
+}
+
+static VALUE arf_get_backend_device_id(VALUE self, VALUE array_val){
+ afstruct* input;
+ int device_id;
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_err flag = af_get_device_id(&device_id, input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return INT2NUM(device_id);
+}
+
+static VALUE arf_set_backend(VALUE self, VALUE backend_val){
+ af_backend backend = arf_backend_type_from_rbsymbol(backend_val);
+
+ af_err flag = af_set_backend(backend);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Qtrue;
+}
diff --git a/ext/mri/cmodules/blas.c b/ext/mri/cmodules/blas.c
new file mode 100644
index 0000000..19ec7d2
--- /dev/null
+++ b/ext/mri/cmodules/blas.c
@@ -0,0 +1,61 @@
+static VALUE arf_matmul(VALUE self, VALUE left_val, VALUE right_val, VALUE left_prop_val, VALUE right_prop_val){
+
+ afstruct* left;
+ afstruct* right;
+ afstruct* result = ALLOC(afstruct);
+
+ Data_Get_Struct(left_val, afstruct, left);
+ Data_Get_Struct(right_val, afstruct, right);
+
+ af_mat_prop left_mat_prop = arf_mat_type_from_rbsymbol(left_prop_val);
+ af_mat_prop right_mat_prop = arf_mat_type_from_rbsymbol(right_prop_val);
+
+ af_err flag = af_matmul(&result->carray, left->carray, right->carray, left_mat_prop, right_mat_prop);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(CLASS_OF(left_val), NULL, arf_free, result);
+}
+
+static VALUE arf_dot(VALUE self, VALUE left_val, VALUE right_val, VALUE left_prop_val, VALUE right_prop_val){
+ afstruct* left;
+ afstruct* right;
+ afstruct* result = ALLOC(afstruct);
+
+ Data_Get_Struct(left_val, afstruct, left);
+ Data_Get_Struct(right_val, afstruct, right);
+
+ af_mat_prop left_mat_prop = arf_mat_type_from_rbsymbol(left_prop_val);
+ af_mat_prop right_mat_prop = arf_mat_type_from_rbsymbol(right_prop_val);
+
+ af_err flag = af_dot(&result->carray, left->carray, right->carray, left_mat_prop, right_mat_prop);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(CLASS_OF(left_val), NULL, arf_free, result);
+}
+
+static VALUE arf_transpose(VALUE self, VALUE input){
+ afstruct* obj;
+ afstruct* result = ALLOC(afstruct);
+
+ Data_Get_Struct(input, afstruct, obj);
+
+ af_err flag = af_transpose(&result->carray, obj->carray, false);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(CLASS_OF(input), NULL, arf_free, result);
+}
+
+static VALUE arf_transpose_inplace(VALUE self, VALUE input){
+ afstruct* obj;
+
+ Data_Get_Struct(input, afstruct, obj);
+
+ af_err flag = af_transpose_inplace(obj->carray, false);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(CLASS_OF(input), NULL, arf_free, obj);
+}
diff --git a/ext/mri/cmodules/cuda.c b/ext/mri/cmodules/cuda.c
new file mode 100644
index 0000000..0d6cf1b
--- /dev/null
+++ b/ext/mri/cmodules/cuda.c
@@ -0,0 +1,18 @@
+static VALUE arf_get_stream(VALUE self, VALUE id){
+ // cudaStream_t* stream;
+ // afcu_get_stream (stream, NUM2INT(id));
+ return Qnil;
+}
+
+static VALUE arf_get_native_id(VALUE self, VALUE cuda_device_id){
+ int native_id;
+ af_err flag = afcu_get_native_id(&native_id, NUM2INT(cuda_device_id));
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return INT2NUM(native_id);
+}
+
+static VALUE arf_set_native_id(VALUE self, VALUE native_id){
+ af_err flag = afcu_set_native_id(native_id);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return Qtrue;
+}
diff --git a/ext/mri/cmodules/data.c b/ext/mri/cmodules/data.c
new file mode 100644
index 0000000..9fafa37
--- /dev/null
+++ b/ext/mri/cmodules/data.c
@@ -0,0 +1,335 @@
+static VALUE arf_constant(int argc, VALUE* argv){
+ afstruct* output = ALLOC(afstruct);
+
+ dim_t ndims = (dim_t)FIX2LONG(argv[0]);
+ dim_t* dimensions = ALLOC_N(dim_t, ndims);
+ dim_t count = 1;
+ for (dim_t index = 0; index < ndims; index++) {
+ dimensions[index] = (dim_t)FIX2LONG(RARRAY_AREF(argv[1], index));
+ count *= dimensions[index];
+ }
+ double data = NUM2DBL(argv[2]);
+
+ af_err flag = af_constant(&output->carray, data, 2, dimensions, f32);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_constant_complex(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_constant_long(int argc, VALUE* argv){
+ afstruct* output = ALLOC(afstruct);
+
+ dim_t ndims = (dim_t)FIX2LONG(argv[0]);
+ dim_t* dimensions = ALLOC_N(dim_t, ndims);
+ dim_t count = 1;
+ for (dim_t index = 0; index < ndims; index++) {
+ dimensions[index] = (dim_t)FIX2LONG(RARRAY_AREF(argv[1], index));
+ count *= dimensions[index];
+ }
+ long data = NUM2LONG(argv[2]);
+
+ af_err flag = af_constant_long(&output->carray, data, 2, dimensions);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_constant_ulong(int argc, VALUE* argv){
+ afstruct* output = ALLOC(afstruct);
+
+ dim_t ndims = (dim_t)FIX2LONG(argv[0]);
+ dim_t* dimensions = ALLOC_N(dim_t, ndims);
+ dim_t count = 1;
+ for (dim_t index = 0; index < ndims; index++) {
+ dimensions[index] = (dim_t)FIX2LONG(RARRAY_AREF(argv[1], index));
+ count *= dimensions[index];
+ }
+ unsigned long data = NUM2LONG(argv[2]);
+
+ af_err flag = af_constant_ulong(&output->carray, data, 2, dimensions);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_range(int argc, VALUE* argv){
+ afstruct* output = ALLOC(afstruct);
+
+ dim_t ndims = (dim_t)FIX2LONG(argv[0]);
+ dim_t* dimensions = ALLOC_N(dim_t, ndims);
+ dim_t count = 1;
+ for (dim_t index = 0; index < ndims; index++) {
+ dimensions[index] = (dim_t)FIX2LONG(RARRAY_AREF(argv[1], index));
+ count *= dimensions[index];
+ }
+ int seq_dim = NUM2INT(argv[2]);
+ af_err flag = af_range(&output->carray, ndims, dimensions, seq_dim, f32);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_iota(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_identity(int argc, VALUE* argv){
+ afstruct* output = ALLOC(afstruct);
+
+ dim_t ndims = (dim_t)FIX2LONG(argv[0]);
+ dim_t* dimensions = ALLOC_N(dim_t, ndims);
+ dim_t count = 1;
+ for (dim_t index = 0; index < ndims; index++) {
+ dimensions[index] = (dim_t)FIX2LONG(RARRAY_AREF(argv[1], index));
+ count *= dimensions[index];
+ }
+
+ af_err flag = af_identity(&output->carray, ndims, dimensions, f32);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_diag_create(VALUE self, VALUE array_val, VALUE num_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_err flag = af_diag_create(&output->carray, input->carray, NUM2INT(num_val));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_diag_extract(VALUE self, VALUE array_val, VALUE num_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_err flag = af_diag_extract(&output->carray, input->carray, NUM2INT(num_val));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_join(VALUE self, VALUE dim_val, VALUE first_array_val, VALUE second_array_val){
+ afstruct* first_array;
+ afstruct* second_array;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(first_array_val, afstruct, first_array);
+ Data_Get_Struct(second_array_val, afstruct, second_array);
+
+ af_err flag = af_join(&output->carray, NUM2INT(dim_val), first_array->carray, second_array->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_join_many(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_tile(VALUE self, VALUE array_val, VALUE x_val, VALUE y_val, VALUE z_val, VALUE w_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_err flag = af_tile(&output->carray, input->carray, NUM2UINT(x_val), NUM2UINT(y_val), NUM2UINT(z_val), NUM2UINT(w_val));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_reorder(VALUE self, VALUE array_val, VALUE x_val, VALUE y_val, VALUE z_val, VALUE w_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_err flag = af_reorder(&output->carray, input->carray, NUM2UINT(x_val), NUM2UINT(y_val), NUM2UINT(z_val), NUM2UINT(w_val));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_shift(VALUE self, VALUE array_val, VALUE x_val, VALUE y_val, VALUE z_val, VALUE w_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_err flag = af_shift(&output->carray, input->carray, NUM2INT(x_val), NUM2INT(y_val), NUM2INT(z_val), NUM2INT(w_val));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_moddims(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_flat(VALUE self, VALUE array_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_err flag = af_flat(&output->carray, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_flip(VALUE self, VALUE array_val, VALUE dim_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_err flag = af_flip(&output->carray, input->carray, NUM2UINT(dim_val));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_lower(VALUE self, VALUE array_val, VALUE is_unit_diag){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_err flag = af_lower(&output->carray, input->carray, RTEST(is_unit_diag));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_upper(VALUE self, VALUE array_val, VALUE is_unit_diag){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_err flag = af_upper(&output->carray, input->carray, RTEST(is_unit_diag));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_select(VALUE self, VALUE array_cond_val, VALUE array_a_val, VALUE array_b_val){
+ afstruct* array_cond;
+ afstruct* array_a;
+ afstruct* array_b;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_cond_val, afstruct, array_cond);
+ Data_Get_Struct(array_a_val, afstruct, array_a);
+ Data_Get_Struct(array_b_val, afstruct, array_b);
+
+ af_err flag = af_select(&output->carray, array_cond->carray, array_a->carray, array_b->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_select_scalar_r(VALUE self, VALUE array_cond_val, VALUE array_a_val, VALUE b_val){
+ afstruct* array_cond;
+ afstruct* array_a;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_cond_val, afstruct, array_cond);
+ Data_Get_Struct(array_a_val, afstruct, array_a);
+
+ af_err flag = af_select_scalar_r(&output->carray, array_cond->carray, array_a->carray, NUM2DBL(b_val));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_select_scalar_l(VALUE self, VALUE array_cond_val, VALUE a_val, VALUE array_b_val){
+ afstruct* array_cond;
+ afstruct* array_b;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_cond_val, afstruct, array_cond);
+ Data_Get_Struct(array_b_val, afstruct, array_b);
+
+ af_err flag = af_select_scalar_l(&output->carray, array_cond->carray, NUM2DBL(a_val), array_b->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_replace(VALUE self, VALUE array_input_val, VALUE array_cond_val, VALUE array_b_val){
+ afstruct* input;
+ afstruct* array_cond;
+ afstruct* array_b;
+
+ Data_Get_Struct(array_input_val, afstruct, input);
+ Data_Get_Struct(array_cond_val, afstruct, array_cond);
+ Data_Get_Struct(array_b_val, afstruct, array_b);
+
+ af_err flag = af_replace(&input->carray, array_cond->carray, array_b->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Qtrue;
+}
+
+static VALUE arf_replace_scalar(VALUE self, VALUE array_input_val, VALUE array_cond_val, VALUE b_val){
+ afstruct* input;
+ afstruct* array_cond;
+
+ Data_Get_Struct(array_input_val, afstruct, input);
+ Data_Get_Struct(array_cond_val, afstruct, array_cond);
+
+ af_err flag = af_replace_scalar(&input->carray, array_cond->carray, NUM2DBL(b_val));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Qtrue;
+}
diff --git a/ext/mri/cmodules/defines.c b/ext/mri/cmodules/defines.c
new file mode 100644
index 0000000..08674c3
--- /dev/null
+++ b/ext/mri/cmodules/defines.c
@@ -0,0 +1,233 @@
+const char* const DTYPE_NAMES[ARF_NUM_DTYPES] = {
+ "f32",
+ "c32",
+ "f64",
+ "c64",
+ "b8",
+ "s32",
+ "u32",
+ "u8",
+ "s64",
+ "u64",
+ "s16",
+ "u16"
+};
+
+const char* const SOURCE_NAMES[ARF_NUM_SOURCES] = {
+ "afDevice", ///< Device pointer
+ "afHost" ///< Host pointer
+};
+
+std::map MAT_PROPERTIES = {
+ {"AF_MAT_NONE", 0},
+ {"AF_MAT_TRANS", 1},
+ {"AF_MAT_CTRANS", 2},
+ {"AF_MAT_CONJ", 4},
+ {"AF_MAT_UPPER", 32},
+ {"AF_MAT_LOWER", 64},
+ {"AF_MAT_DIAG_UNIT", 128},
+ {"AF_MAT_SYM", 512},
+ {"AF_MAT_POSDEF", 1024},
+ {"AF_MAT_ORTHOG", 2048},
+ {"AF_MAT_TRI_DIAG", 4096},
+ {"AF_MAT_BLOCK_DIAG", 8192}
+};
+
+const char* const NORM_TYPES[ARF_NUM_NORM_TYPES] = {
+ "AF_NORM_VECTOR_1", ///< treats the input as a vector and returns the sum of absolute values
+ "AF_NORM_VECTOR_INF", ///< treats the input as a vector and returns the max of absolute values
+ "AF_NORM_VECTOR_2", ///< treats the input as a vector and returns euclidean norm
+ "AF_NORM_VECTOR_P", ///< treats the input as a vector and returns the p-norm
+ "AF_NORM_MATRIX_1", ///< return the max of column sums
+ "AF_NORM_MATRIX_INF", ///< return the max of row sums
+ "AF_NORM_MATRIX_2", ///< returns the max singular value). Currently NOT SUPPORTED
+ "AF_NORM_MATRIX_L_PQ", ///< returns Lpq-norm
+ "AF_NORM_EUCLID" ///< The default. Same as AF_NORM_VECTOR_2
+};
+
+std::map MOMENT_TYPES = {
+ {"AF_MOMENT_M00", 1},
+ {"AF_MOMENT_M01", 2},
+ {"AF_MOMENT_M10", 4},
+ {"AF_MOMENT_M11", 8}
+ //AF_MOMENT_FIRST_ORDER = AF_MOMENT_M00 | AF_MOMENT_M01 | AF_MOMENT_M10 | AF_MOMENT_M11
+};
+
+std::map BACKEND_TYPES = {
+ {"AF_BACKEND_DEFAULT" , 0}, ///< Default backend order: OpenCL -> CUDA -> CPU
+ {"AF_BACKEND_CPU" , 1}, ///< CPU a.k.a sequential algorithms
+ {"AF_BACKEND_CUDA" , 2}, ///< CUDA Compute Backend
+ {"AF_BACKEND_OPENCL" , 4} ///< OpenCL Compute Backend
+};
+
+std::map RANDOM_ENGINE_TYPES = {
+ {"AF_RANDOM_ENGINE_PHILOX_4X32_10" , 100}, //Philox variant with N = 4, W = 32 and Rounds = 10
+ {"AF_RANDOM_ENGINE_THREEFRY_2X32_16" , 200}, //Threefry variant with N = 2, W = 32 and Rounds = 16
+ {"AF_RANDOM_ENGINE_MERSENNE_GP11213" , 300}, //Mersenne variant with MEXP = 11213
+ {"AF_RANDOM_ENGINE_PHILOX" , 100}, //Resolves to Philox 4x32_10
+ {"AF_RANDOM_ENGINE_THREEFRY" , 200}, //Resolves to Threefry 2X32_16
+ {"AF_RANDOM_ENGINE_MERSENNE" , 300}, //Resolves to Mersenne GP 11213
+ {"AF_RANDOM_ENGINE_DEFAULT" , 100}, //Resolves to Philox
+};
+
+std::map ERROR_TYPES = {
+ {"AF_SUCCESS" , 0},
+ {"AF_ERR_NO_MEM" , 101},
+ {"AF_ERR_DRIVER" , 102},
+ {"AF_ERR_RUNTIME" , 103},
+ {"AF_ERR_INVALID_ARRAY" , 201},
+ {"AF_ERR_ARG" , 202},
+ {"AF_ERR_SIZE" , 203},
+ {"AF_ERR_TYPE" , 204},
+ {"AF_ERR_DIFF_TYPE" , 205},
+ {"AF_ERR_BATCH" , 207},
+ {"AF_ERR_DEVICE" , 208},
+ {"AF_ERR_NOT_SUPPORTED" , 301},
+ {"AF_ERR_NOT_CONFIGURED" , 302},
+ {"AF_ERR_NONFREE" , 303},
+ {"AF_ERR_NO_DBL" , 401},
+ {"AF_ERR_NO_GFX" , 402},
+ {"AF_ERR_LOAD_LIB" , 501},
+ {"AF_ERR_LOAD_SYM" , 502},
+ {"AF_ERR_ARR_BKND_MISMATCH" , 503},
+ {"AF_ERR_INTERNAL" , 998},
+ {"AF_ERR_UNKNOWN" , 999}
+};
+
+const char* const STORAGE_TYPES[ARF_NUM_STORAGE_TYPES] = {
+ "AF_STORAGE_DENSE", ///< Storage type is dense
+ "AF_STORAGE_CSR", ///< Storage type is CSR
+ "AF_STORAGE_CSC", ///< Storage type is CSC
+ "AF_STORAGE_COO", ///< Storage type is COO
+};
+
+void arf_handle_exception(af_err error_code){
+ for(std::map::value_type& entry : ERROR_TYPES) {
+ if (error_code == entry.second) {
+ rb_raise(rb_eArgError, entry.first);
+ break;
+ }
+ }
+}
+
+af_dtype arf_dtype_from_rbsymbol(VALUE sym) {
+ ID sym_id = SYM2ID(sym);
+
+ for (size_t index = 0; index < ARF_NUM_DTYPES; ++index) {
+ if (sym_id == rb_intern(DTYPE_NAMES[index])) {
+ return static_cast(index);
+ }
+ }
+
+ VALUE str = rb_any_to_s(sym);
+ rb_raise(rb_eArgError, "invalid data type symbol (:%s) specified", RSTRING_PTR(str));
+}
+
+af_source arf_source_from_rbsymbol(VALUE sym) {
+ ID sym_id = SYM2ID(sym);
+
+ for (size_t index = 0; index < ARF_NUM_SOURCES; ++index) {
+ if (sym_id == rb_intern(SOURCE_NAMES[index])) {
+ return static_cast(index);
+ }
+ }
+
+ VALUE str = rb_any_to_s(sym);
+ rb_raise(rb_eArgError, "invalid data type symbol (:%s) specified", RSTRING_PTR(str));
+}
+
+af_mat_prop arf_mat_type_from_rbsymbol(VALUE sym) {
+ ID sym_id = SYM2ID(sym);
+
+ for(std::map::value_type& entry : MAT_PROPERTIES) {
+ if (sym_id == rb_intern(entry.first)) {
+ return static_cast(entry.second);
+ }
+ }
+
+ VALUE str = rb_any_to_s(sym);
+ rb_raise(rb_eArgError, "invalid matrix type symbol (:%s) specified", RSTRING_PTR(str));
+}
+
+af_norm_type arf_norm_type_from_rbsymbol(VALUE sym) {
+ ID sym_id = SYM2ID(sym);
+
+ for (size_t index = 0; index < ARF_NUM_NORM_TYPES; ++index) {
+ if (sym_id == rb_intern(NORM_TYPES[index])) {
+ return static_cast(index);
+ }
+ }
+
+ VALUE str = rb_any_to_s(sym);
+ rb_raise(rb_eArgError, "invalid norm type symbol (:%s) specified", RSTRING_PTR(str));
+}
+
+af_moment_type arf_moment_type_from_rbsymbol(VALUE sym) {
+ ID sym_id = SYM2ID(sym);
+
+ for(std::map::value_type& entry : MOMENT_TYPES) {
+ if (sym_id == rb_intern(entry.first)) {
+ return static_cast(entry.second);
+ }
+ }
+
+ VALUE str = rb_any_to_s(sym);
+ rb_raise(rb_eArgError, "invalid moment type symbol (:%s) specified", RSTRING_PTR(str));
+}
+
+af_backend arf_backend_type_from_rbsymbol(VALUE sym) {
+ ID sym_id = SYM2ID(sym);
+
+ for(std::map::value_type& entry : BACKEND_TYPES) {
+ if (sym_id == rb_intern(entry.first)) {
+ return static_cast(entry.second);
+ }
+ }
+
+ VALUE str = rb_any_to_s(sym);
+ rb_raise(rb_eArgError, "invalid backend type symbol (:%s) specified", RSTRING_PTR(str));
+}
+
+af_random_engine_type arf_randome_engine_type_from_rbsymbol(VALUE sym) {
+ ID sym_id = SYM2ID(sym);
+
+ for(std::map::value_type& entry : RANDOM_ENGINE_TYPES) {
+ if (sym_id == rb_intern(entry.first)) {
+ return static_cast(entry.second);
+ }
+ }
+
+ VALUE str = rb_any_to_s(sym);
+ rb_raise(rb_eArgError, "invalid engine type symbol (:%s) specified", RSTRING_PTR(str));
+}
+
+af_storage arf_storage_type_from_rbsymbol(VALUE sym){
+ ID sym_id = SYM2ID(sym);
+
+ for (size_t index = 0; index < ARF_NUM_STORAGE_TYPES; ++index) {
+ if (sym_id == rb_intern(STORAGE_TYPES[index])) {
+ return static_cast(index);
+ }
+ }
+
+ VALUE str = rb_any_to_s(sym);
+ rb_raise(rb_eArgError, "invalid storage type symbol (:%s) specified", RSTRING_PTR(str));
+}
+
+const char* get_backend_name(af_backend backend){
+ for(std::map::value_type& entry : BACKEND_TYPES) {
+ if (backend == entry.second) {
+ return entry.first;
+ }
+ }
+ rb_raise(rb_eArgError, "Something went wrong!");
+}
+
+const char* get_random_engine_name(af_random_engine_type engine){
+ for(std::map::value_type& entry : RANDOM_ENGINE_TYPES) {
+ if (engine == entry.second) {
+ return entry.first;
+ }
+ }
+ rb_raise(rb_eArgError, "Something went wrong!");
+}
diff --git a/ext/mri/cmodules/device.c b/ext/mri/cmodules/device.c
new file mode 100644
index 0000000..cad5699
--- /dev/null
+++ b/ext/mri/cmodules/device.c
@@ -0,0 +1,174 @@
+static VALUE arf_info(VALUE self){
+ af_err flag = af_info();
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return Qtrue;
+}
+
+static VALUE arf_init2(VALUE self){
+ af_err flag = af_init();
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return Qtrue;
+}
+
+static VALUE arf_info_string(VALUE self, VALUE bool_val){
+ char* str;
+ af_err flag = af_info_string(&str, RTEST(bool_val));
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return rb_str_new_cstr(str);
+}
+
+static VALUE arf_device_info(VALUE self, VALUE name_val, VALUE platform_val, VALUE toolkit_val, VALUE compute_val){
+ char* d_name = ALLOC_N(char, sizeof(char) * 64);
+ char* d_platform = ALLOC_N(char, sizeof(char) * 10);
+ char* d_toolkit = ALLOC_N(char, sizeof(char) * 64);
+ char* d_compute = ALLOC_N(char, sizeof(char) * 10);
+
+ af_err flag = af_device_info(d_name, d_platform, d_toolkit, d_compute);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ rb_str_cat2(name_val, d_name);
+ rb_str_cat2(platform_val, d_platform);
+ rb_str_cat2(toolkit_val, d_toolkit);
+ rb_str_cat2(compute_val, d_compute);
+
+ return Qtrue;
+}
+
+static VALUE arf_get_device_count(VALUE self){
+ int num_of_devices;
+ af_err flag = af_get_device_count(&num_of_devices);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return INT2NUM(num_of_devices);
+}
+
+static VALUE arf_get_dbl_support(VALUE self, VALUE device){
+ bool available;
+ af_err flag = af_get_dbl_support(&available, NUM2INT(device));
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return available ? Qtrue : Qfalse;
+}
+
+static VALUE arf_set_device(VALUE self, VALUE device){
+ af_err flag = af_set_device(NUM2INT(device));
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return Qtrue;
+}
+
+static VALUE arf_get_device(VALUE self){
+ int device;
+ af_err flag = af_get_device(&device);
+ return INT2NUM(device);
+}
+
+static VALUE arf_sync(VALUE self, VALUE device_val){
+ af_err flag = af_sync(NUM2INT(device_val));
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return Qtrue;
+}
+
+static VALUE arf_alloc_device(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_free_device(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_alloc_pinned(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_free_pinned(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_alloc_host(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_free_host(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_device_array(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_device_mem_info(VALUE self){
+ size_t alloc_bytes, alloc_buffers, lock_bytes, lock_buffers;
+ af_err flag = af_device_mem_info( &alloc_bytes, &alloc_buffers, &lock_bytes, &lock_buffers);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ printf("Allocated Bytes: %d\nAllocated buffers: %d\nLock Bytes: %d\nLock Buffers: %d\n",
+ alloc_bytes, alloc_buffers, lock_bytes, lock_buffers);
+ return Qtrue;
+}
+
+static VALUE arf_print_mem_info(VALUE self, VALUE msg_val, VALUE device_id_val){
+ const char* msg = StringValuePtr(msg_val);
+ af_err flag = af_print_mem_info( msg, NUM2INT(device_id_val));
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return Qtrue;
+}
+
+static void arf_device_gc(VALUE self){
+ af_err flag = af_device_gc();
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+}
+
+static VALUE arf_set_mem_step_size(VALUE self, VALUE step_bytes){
+ af_err flag = af_set_mem_step_size(NUM2UINT(step_bytes));
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return Qtrue;
+}
+
+static VALUE arf_get_mem_step_size(VALUE self){
+ size_t step_bytes;
+ af_err flag = af_get_mem_step_size(&step_bytes);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return UINT2NUM(step_bytes);
+}
+
+static VALUE arf_lock_device_ptr(VALUE self, VALUE array_val){
+ afstruct* input;
+ Data_Get_Struct(array_val, afstruct, input);
+ af_err flag = af_lock_device_ptr(input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return Qtrue;
+}
+
+static VALUE arf_unlock_device_ptr(VALUE self, VALUE array_val){
+ afstruct* input;
+ Data_Get_Struct(array_val, afstruct, input);
+ af_err flag = af_unlock_device_ptr(input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return Qtrue;
+}
+
+static VALUE arf_lock_array(VALUE self, VALUE array_val){
+ afstruct* input;
+ Data_Get_Struct(array_val, afstruct, input);
+ af_err flag = af_lock_array(input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return Qtrue;
+}
+
+static VALUE arf_unlock_array(VALUE self, VALUE array_val){
+ afstruct* input;
+ Data_Get_Struct(array_val, afstruct, input);
+ af_err flag = af_unlock_array(input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return Qtrue;
+}
+
+static VALUE arf_is_locked_array(VALUE self, VALUE array_val){
+ bool res;
+ afstruct* input;
+ Data_Get_Struct(array_val, afstruct, input);
+ af_err flag = af_is_locked_array(&res, input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return res ? Qtrue : Qfalse;
+}
+
+static VALUE arf_get_device_ptr(VALUE self){
+ return Qnil;
+}
diff --git a/ext/mri/cmodules/index.c b/ext/mri/cmodules/index.c
new file mode 100644
index 0000000..6c7896b
--- /dev/null
+++ b/ext/mri/cmodules/index.c
@@ -0,0 +1,39 @@
+static VALUE arf_index(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_lookup(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_assign_seq(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_index_gen(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_assign_gen(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_create_indexers(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_set_array_indexer(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_set_seq_indexer(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_set_seq_param_indexer(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_release_indexers(VALUE self){
+ return Qnil;
+}
diff --git a/ext/mri/cmodules/lapack.c b/ext/mri/cmodules/lapack.c
new file mode 100644
index 0000000..55f100f
--- /dev/null
+++ b/ext/mri/cmodules/lapack.c
@@ -0,0 +1,186 @@
+static VALUE arf_svd_func(VALUE self, VALUE u_val, VALUE s_val, VALUE vt_val, VALUE val){
+ afstruct* input;
+ afstruct* u;
+ afstruct* s;
+ afstruct* vt;
+
+ Data_Get_Struct(val, afstruct, input);
+ Data_Get_Struct(u_val, afstruct, u);
+ Data_Get_Struct(s_val, afstruct, s);
+ Data_Get_Struct(vt_val, afstruct, vt);
+
+ af_err flag = af_svd(&u->carray, &s->carray, &vt->carray, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Qtrue;
+}
+
+static VALUE arf_svd_inplace_func(VALUE self, VALUE val){
+ afstruct* input;
+ afstruct* u = ALLOC(afstruct);
+ afstruct* s = ALLOC(afstruct);
+ afstruct* vt = ALLOC(afstruct);
+
+ Data_Get_Struct(val, afstruct, input);
+
+ af_err flag = af_svd_inplace(&u->carray, &s->carray, &vt->carray, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(CLASS_OF(val), NULL, arf_free, u);
+}
+
+static VALUE arf_lu_func(VALUE self, VALUE lower_val, VALUE upper_val, VALUE pivot_val, VALUE val){
+ afstruct* input;
+ afstruct* lower;
+ afstruct* upper;
+ afstruct* pivot;
+
+ Data_Get_Struct(val, afstruct, input);
+ Data_Get_Struct(lower_val, afstruct, lower);
+ Data_Get_Struct(upper_val, afstruct, upper);
+ Data_Get_Struct(pivot_val, afstruct, pivot);
+
+ af_lu(&lower->carray, &upper->carray, &pivot->carray, input->carray);
+ return Qtrue;
+}
+
+static VALUE arf_lu_inplace_func(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_qr_func(VALUE self, VALUE q_val, VALUE r_val, VALUE tau_val, VALUE val){
+ afstruct* input;
+ afstruct* q;
+ afstruct* r;
+ afstruct* tau;
+
+ Data_Get_Struct(val, afstruct, input);
+ Data_Get_Struct(q_val, afstruct, q);
+ Data_Get_Struct(r_val, afstruct, r);
+ Data_Get_Struct(tau_val, afstruct, tau);
+
+ af_err flag = af_qr(&q->carray, &r->carray, &tau->carray, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Qfalse;
+}
+
+static VALUE arf_qr_inplace_func(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_cholesky_func(VALUE self, VALUE output_val, VALUE val, VALUE is_upper_val){
+ afstruct* input;
+ afstruct* output;
+ int info;
+
+ Data_Get_Struct(val, afstruct, input);
+ Data_Get_Struct(output_val, afstruct, output);
+
+ af_err flag = af_cholesky(&output->carray, &info, input->carray, is_upper_val);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return INT2NUM(info);
+}
+
+static VALUE arf_cholesky_inplace_func(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_solve(VALUE self, VALUE lhs_val, VALUE rhs_val){
+
+ afstruct* lhs;
+ afstruct* rhs;
+ afstruct* result = ALLOC(afstruct);
+
+ Data_Get_Struct(lhs_val, afstruct, lhs);
+ Data_Get_Struct(rhs_val, afstruct, rhs);
+
+ af_err flag = af_solve(&result->carray, lhs->carray, rhs->carray, AF_MAT_NONE);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(CLASS_OF(lhs_val), NULL, arf_free, result);
+}
+
+static VALUE arf_solve_lu(VALUE self, VALUE lhs_val, VALUE rhs_val, VALUE piv_val){
+ afstruct* lhs;
+ afstruct* rhs;
+ afstruct* piv;
+ afstruct* result = ALLOC(afstruct);
+
+ Data_Get_Struct(lhs_val, afstruct, lhs);
+ Data_Get_Struct(rhs_val, afstruct, rhs);
+ Data_Get_Struct(piv_val, afstruct, piv);
+
+ af_err flag = af_solve_lu(&result->carray, lhs->carray, piv->carray, rhs->carray, AF_MAT_NONE);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(CLASS_OF(lhs_val), NULL, arf_free, result);
+}
+
+static VALUE arf_inverse(VALUE self, VALUE val){
+ afstruct* matrix;
+ afstruct* result = ALLOC(afstruct);
+
+ Data_Get_Struct(val, afstruct, matrix);
+
+ af_err flag = af_inverse(&result->carray, matrix->carray, AF_MAT_NONE);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(CLASS_OF(val), NULL, arf_free, result);
+}
+
+static VALUE arf_rank(VALUE self, VALUE val){
+ afstruct* matrix;
+ uint rank;
+
+ Data_Get_Struct(val, afstruct, matrix);
+
+ af_err flag = af_rank(&rank, matrix->carray, 0.001);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return UINT2NUM(rank);
+}
+
+static VALUE arf_det(VALUE self, VALUE val){
+ afstruct* matrix;
+ double det_real, det_imag;
+
+ Data_Get_Struct(val, afstruct, matrix);
+
+ af_err flag = af_det(&det_real, &det_imag, matrix->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return DBL2NUM(det_real);
+}
+
+static VALUE arf_norm(VALUE self, VALUE val){
+ afstruct* matrix;
+ double norm;
+ double p = 0;
+ double q = 0;
+ Data_Get_Struct(val, afstruct, matrix);
+ af_err flag = af_norm(&norm, matrix->carray, AF_NORM_EUCLID, p, q);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return DBL2NUM(norm);
+}
+
+static VALUE arf_is_lapack_available(VALUE self){
+ bool output;
+ af_err flag = af_is_lapack_available(&output);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return output ? Qtrue : Qfalse;
+}
diff --git a/ext/mri/cmodules/opencl.c b/ext/mri/cmodules/opencl.c
new file mode 100644
index 0000000..6b3e103
--- /dev/null
+++ b/ext/mri/cmodules/opencl.c
@@ -0,0 +1,83 @@
+std::map AFCL_DEVICE_TYPES = {
+ {"AFCL_DEVICE_TYPE_CPU", 0},
+ {"CL_DEVICE_TYPE_CPU", 1},
+ {"AFCL_DEVICE_TYPE_GPU", 2},
+ {"CL_DEVICE_TYPE_GPU", 3},
+ {"AFCL_DEVICE_TYPE_ACC", 4},
+ {"CL_DEVICE_TYPE_ACCELERATOR", 5},
+ {"AFCL_DEVICE_TYPE_UNKNOWN", -1}
+};
+
+std::map AFCL_PLATFORM_TYPES = {
+ {"AFCL_PLATFORM_AMD", 0},
+ {"AFCL_PLATFORM_APPLE", 1},
+ {"AFCL_PLATFORM_INTEL", 2},
+ {"AFCL_PLATFORM_NVIDIA", 3},
+ {"AFCL_PLATFORM_BEIGNET", 4},
+ {"AFCL_PLATFORM_POCL", 5},
+ {"AFCL_PLATFORM_UNKNOWN", -1}
+};
+
+
+static VALUE arf_get_context(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_get_queue(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_get_device_id(VALUE self){
+ cl_device_id id;
+ af_err flag = afcl_get_device_id(&id);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return Qnil;
+}
+
+static VALUE arf_set_device_id(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_add_device_context(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_set_device_context(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_delete_device_context(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_get_device_type(VALUE self){
+ afcl_device_type device;
+ af_err flag = afcl_get_device_type(&device);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return rb_str_new_cstr(get_cl_device_name(device));
+}
+
+static VALUE arf_get_platform(VALUE self){
+ afcl_platform platform;
+ af_err flag = afcl_get_platform(&platform);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ return rb_str_new_cstr(get_cl_platform_name(platform));
+}
+
+const char* get_cl_device_name(afcl_device_type device){
+ for(std::map::value_type& entry : AFCL_DEVICE_TYPES) {
+ if (device == entry.second) {
+ return entry.first;
+ }
+ }
+ rb_raise(rb_eArgError, "Couldn't detect device!");
+}
+
+const char* get_cl_platform_name(afcl_platform platform){
+ for(std::map::value_type& entry : AFCL_PLATFORM_TYPES) {
+ if (platform == entry.second) {
+ return entry.first;
+ }
+ }
+ rb_raise(rb_eArgError, "Couldn't detect platform!");
+}
diff --git a/ext/mri/cmodules/random.c b/ext/mri/cmodules/random.c
new file mode 100644
index 0000000..033a7e8
--- /dev/null
+++ b/ext/mri/cmodules/random.c
@@ -0,0 +1,203 @@
+static VALUE arf_create_random_engine(VALUE self, VALUE type_val, VALUE seed_val){
+ afrandomenginestruct* output = ALLOC(afrandomenginestruct);
+ af_random_engine_type rtype = arf_randome_engine_type_from_rbsymbol(type_val);
+
+ af_err flag = af_create_random_engine(&output->cengine, AF_RANDOM_ENGINE_DEFAULT, NUM2ULL(seed_val) ) ;
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(Random, NULL, arf_engine_free, output);
+}
+
+static VALUE arf_retain_random_engine(VALUE self, VALUE engine_val){
+ afrandomenginestruct* output = ALLOC(afrandomenginestruct);
+ afrandomenginestruct* engine;
+
+ Data_Get_Struct(engine_val, afrandomenginestruct, engine);
+
+ af_err flag = af_retain_random_engine ( &output->cengine, engine->cengine);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(Random, NULL, arf_engine_free, output);
+}
+
+static VALUE arf_random_engine_set_type(VALUE self, VALUE engine_val, VALUE type_val){
+ af_random_engine_type rtype = arf_randome_engine_type_from_rbsymbol(type_val);
+ afrandomenginestruct* engine;
+
+ Data_Get_Struct(engine_val, afrandomenginestruct, engine);
+
+ af_err flag = af_random_engine_set_type(&engine->cengine, rtype);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Qtrue;
+}
+
+static VALUE arf_random_engine_get_type(VALUE self, VALUE engine_val){
+ af_random_engine_type rtype;
+ afrandomenginestruct* engine;
+
+ Data_Get_Struct(engine_val, afrandomenginestruct, engine);
+
+ af_err flag = af_random_engine_get_type(&rtype, engine->cengine);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ const char* rengine = get_random_engine_name(rtype);
+ return rb_str_new_cstr(rengine);
+}
+
+static VALUE arf_random_uniform(VALUE self, VALUE ndims_val, VALUE dim_val, VALUE engine_val){
+ afstruct* out_array = ALLOC(afstruct);
+ afrandomenginestruct* engine;
+
+ Data_Get_Struct(engine_val, afrandomenginestruct, engine);
+
+ dim_t ndims = (dim_t)FIX2LONG(ndims_val);
+ dim_t* dimensions = ALLOC_N(dim_t, ndims);
+ dim_t count = 1;
+ for (dim_t index = 0; index < ndims; index++) {
+ dimensions[index] = (dim_t)FIX2LONG(RARRAY_AREF(dim_val, index));
+ count *= dimensions[index];
+ }
+
+ af_err flag = af_random_uniform(&out_array->carray, ndims, dimensions, f32, engine->cengine);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, out_array);
+}
+
+static VALUE arf_random_normal(VALUE self, VALUE ndims_val, VALUE dim_val, VALUE engine_val){
+ afstruct* out_array = ALLOC(afstruct);
+ afrandomenginestruct* engine;
+
+ Data_Get_Struct(engine_val, afrandomenginestruct, engine);
+
+ dim_t ndims = (dim_t)FIX2LONG(ndims_val);
+ dim_t* dimensions = ALLOC_N(dim_t, ndims);
+ dim_t count = 1;
+ for (dim_t index = 0; index < ndims; index++) {
+ dimensions[index] = (dim_t)FIX2LONG(RARRAY_AREF(dim_val, index));
+ count *= dimensions[index];
+ }
+
+ af_err flag = af_random_uniform(&out_array->carray, ndims, dimensions, f32, engine->cengine);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, out_array);
+}
+
+static VALUE arf_random_engine_set_seed(VALUE self, VALUE engine_val ,VALUE seed_val){
+ afrandomenginestruct* engine;
+
+ Data_Get_Struct(engine_val, afrandomenginestruct, engine);
+
+ af_err flag = af_random_engine_set_seed (&engine->cengine, NUM2ULL(seed_val));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(Random, NULL, arf_engine_free, engine);
+}
+
+static VALUE arf_get_default_random_engine(VALUE self){
+ afrandomenginestruct* output = ALLOC(afrandomenginestruct);
+
+ af_err flag = af_get_default_random_engine(&output->cengine) ;
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(Random, NULL, arf_engine_free, output);
+}
+
+static VALUE arf_set_default_random_engine_type(VALUE self, VALUE type_val){
+ af_random_engine_type rtype = arf_randome_engine_type_from_rbsymbol(type_val);
+
+ af_err flag = af_set_default_random_engine_type(rtype);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Qtrue;
+}
+
+static VALUE arf_random_engine_get_seed(VALUE self, VALUE engine_val){
+ afrandomenginestruct* engine;
+ uintl seed;
+
+ Data_Get_Struct(engine_val, afrandomenginestruct, engine);
+
+ af_err flag = af_random_engine_get_seed(&seed, engine->cengine);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return ULL2NUM(seed);
+}
+
+static VALUE arf_release_random_engine(VALUE self, VALUE engine_val){
+ afrandomenginestruct* engine;
+
+ Data_Get_Struct(engine_val, afrandomenginestruct, engine);
+
+ af_err flag = af_release_random_engine(engine);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Qtrue;
+}
+
+static VALUE arf_randu(VALUE self, VALUE ndims_val, VALUE dim_val){
+ afstruct* out_array = ALLOC(afstruct);
+
+ dim_t ndims = (dim_t)FIX2LONG(ndims_val);
+ dim_t* dimensions = ALLOC_N(dim_t, ndims);
+ dim_t count = 1;
+ for (dim_t index = 0; index < ndims; index++) {
+ dimensions[index] = (dim_t)FIX2LONG(RARRAY_AREF(dim_val, index));
+ count *= dimensions[index];
+ }
+
+ af_err flag = af_randu(&out_array->carray, ndims, dimensions,f32);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, out_array);
+}
+
+static VALUE arf_randn(VALUE self, VALUE ndims_val, VALUE dim_val){
+ afstruct* out_array = ALLOC(afstruct);
+
+ dim_t ndims = (dim_t)FIX2LONG(ndims_val);
+ dim_t* dimensions = ALLOC_N(dim_t, ndims);
+ dim_t count = 1;
+ for (dim_t index = 0; index < ndims; index++) {
+ dimensions[index] = (dim_t)FIX2LONG(RARRAY_AREF(dim_val, index));
+ count *= dimensions[index];
+ }
+
+ af_err flag = af_randn(&out_array->carray, ndims, dimensions,f32);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, out_array);
+}
+
+static VALUE arf_set_seed(VALUE self, VALUE seed){
+ af_err flag = af_set_seed(NUM2ULL(seed));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Qtrue;
+}
+
+static VALUE arf_get_seed(VALUE self){
+ uintl seed;
+
+ af_err flag = af_get_seed(&seed);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return ULL2NUM(seed);
+}
diff --git a/ext/mri/cmodules/sparse.c b/ext/mri/cmodules/sparse.c
new file mode 100644
index 0000000..fcb80ea
--- /dev/null
+++ b/ext/mri/cmodules/sparse.c
@@ -0,0 +1,154 @@
+static VALUE arf_create_sparse_array(VALUE self, VALUE shape_array, VALUE values_array, VALUE rowIdx_val, VALUE colIdx_val, VALUE stype_val){
+ afstruct* output = ALLOC(afstruct);
+ afstruct* values;
+ afstruct* rowIdx;
+ afstruct* colIdx;
+
+ Data_Get_Struct(values_array, afstruct, values);
+ Data_Get_Struct(rowIdx_val, afstruct, rowIdx);
+ Data_Get_Struct(colIdx_val, afstruct, colIdx);
+
+ af_storage stype = arf_storage_type_from_rbsymbol(stype_val);
+
+ dim_t nRows = (dim_t)FIX2LONG(RARRAY_AREF(shape_array, 0));
+ dim_t nCols = (dim_t)FIX2LONG(RARRAY_AREF(shape_array, 1));
+
+ af_err flag = af_create_sparse_array(&output->carray, nRows, nCols, values->carray, rowIdx->carray, colIdx->carray, stype);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_create_sparse_array_from_ptr(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_create_sparse_array_from_dense(VALUE self, VALUE dense_val, VALUE stype_val){
+ afstruct* output = ALLOC(afstruct);
+ afstruct* dense;
+
+ Data_Get_Struct(dense_val, afstruct, dense);
+
+ af_storage stype = arf_storage_type_from_rbsymbol(stype_val);
+
+ af_err flag = af_create_sparse_array_from_dense(&output->carray, dense->carray, stype);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_sparse_convert_to(VALUE self, VALUE input_val, VALUE dest_storage_val){
+ afstruct* output = ALLOC(afstruct);
+ afstruct* input;
+
+ Data_Get_Struct(input_val, afstruct, input);
+
+ af_storage dest_storage = arf_storage_type_from_rbsymbol(dest_storage_val);
+
+ af_err flag = af_sparse_convert_to(&output->carray, input->carray, dest_storage);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_sparse_to_dense(VALUE self, VALUE sparse_array){
+ afstruct* dense = ALLOC(afstruct);
+ afstruct* sparse;
+
+ Data_Get_Struct(sparse_array, afstruct, sparse);
+
+ af_err flag = af_sparse_to_dense(&dense->carray, sparse->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, dense);
+}
+
+static VALUE arf_sparse_get_info_func(VALUE self, VALUE values_val, VALUE rowIdx_val, VALUE colIdx_val, VALUE input_val){
+ afstruct* input;
+ afstruct* values;
+ afstruct* rowIdx;
+ afstruct* colIdx;
+ af_storage stype;
+
+ Data_Get_Struct(input_val, afstruct, input);
+ Data_Get_Struct(values_val, afstruct, values);
+ Data_Get_Struct(rowIdx_val, afstruct, rowIdx);
+ Data_Get_Struct(colIdx_val, afstruct, colIdx);
+
+ af_err flag = af_sparse_get_info( &values->carray, &rowIdx->carray, &colIdx->carray, &stype, input->carray );
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return rb_str_new_cstr(STORAGE_TYPES[stype]);
+}
+
+static VALUE arf_sparse_get_values(VALUE self, VALUE input_val){
+ afstruct* output = ALLOC(afstruct);
+ afstruct* input;
+
+ Data_Get_Struct(input_val, afstruct, input);
+
+ af_err flag = af_sparse_get_values(&output->carray, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_sparse_get_row_idx(VALUE self, VALUE input_val){
+ afstruct* output = ALLOC(afstruct);
+ afstruct* input;
+
+ Data_Get_Struct(input_val, afstruct, input);
+
+ af_err flag = af_sparse_get_row_idx(&output->carray, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_sparse_get_col_idx(VALUE self, VALUE input_val){
+ afstruct* output = ALLOC(afstruct);
+ afstruct* input;
+
+ Data_Get_Struct(input_val, afstruct, input);
+
+ af_err flag = af_sparse_get_col_idx(&output->carray, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_sparse_get_nnz(VALUE self, VALUE input_val){
+ dim_t out;
+ afstruct* input;
+
+ Data_Get_Struct(input_val, afstruct, input);
+
+ af_err flag = af_sparse_get_nnz( &out, input);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return ULL2NUM(out);
+}
+
+static VALUE arf_sparse_get_storage(VALUE self, VALUE input_val){
+ afstruct* input;
+ Data_Get_Struct(input_val, afstruct, input);
+
+ af_storage storage;
+
+ af_err flag = af_sparse_get_storage(&storage , input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return rb_str_new_cstr(STORAGE_TYPES[storage]);
+}
diff --git a/ext/mri/cmodules/statistics.c b/ext/mri/cmodules/statistics.c
new file mode 100644
index 0000000..937c3d0
--- /dev/null
+++ b/ext/mri/cmodules/statistics.c
@@ -0,0 +1,200 @@
+static VALUE arf_mean(VALUE self, VALUE array_val, VALUE dim_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_err flag = af_mean(&output->carray, input->carray, NUM2UINT(dim_val));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_mean_weighted(VALUE self, VALUE array_val, VALUE weighted_array_val, VALUE dim_val){
+ afstruct* input;
+ afstruct* weighted_array;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+ Data_Get_Struct(weighted_array_val, afstruct, weighted_array);
+
+ af_err flag = af_mean_weighted(&output->carray, input->carray, weighted_array->carray, NUM2UINT(dim_val));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_var(VALUE self, VALUE array_val, VALUE is_biased, VALUE dim_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_err flag = af_var(&output->carray, input->carray, RTEST(is_biased), NUM2UINT(dim_val));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_var_weighted(VALUE self, VALUE array_val, VALUE weighted_array_val, VALUE dim_val){
+ afstruct* input;
+ afstruct* weighted_array;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+ Data_Get_Struct(weighted_array_val, afstruct, weighted_array);
+
+ af_err flag = af_var_weighted(&output->carray, input->carray, weighted_array->carray, NUM2UINT(dim_val));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_stdev(VALUE self, VALUE array_val, VALUE dim_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_err flag = af_stdev(&output->carray, input->carray, NUM2UINT(dim_val));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_cov(VALUE self, VALUE first_array_val, VALUE second_array_val, VALUE is_biased){
+ afstruct* output = ALLOC(afstruct);
+
+ afstruct* first_array;
+ afstruct* second_array;
+
+ Data_Get_Struct(first_array_val, afstruct, first_array);
+ Data_Get_Struct(second_array_val, afstruct, second_array);
+
+ af_err flag = af_cov(&output->carray, first_array->carray, second_array->carray, RTEST(is_biased));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_median(VALUE self, VALUE array_val, VALUE dim_val){
+ afstruct* input;
+ afstruct* output = ALLOC(afstruct);
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_err flag = af_median(&output->carray, input->carray, NUM2UINT(dim_val));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+ af_print_array(output->carray);
+
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, output);
+}
+
+static VALUE arf_mean_all(VALUE self, VALUE array_val){
+ afstruct* input;
+ double real_part, imag_part;
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_err flag = af_mean_all(&real_part, &imag_part, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return DBL2NUM(real_part);
+}
+
+static VALUE arf_mean_all_weighted(VALUE self, VALUE array_val, VALUE weighted_array_val){
+ afstruct* input;
+ afstruct* weighted_array;
+ double real_part, imag_part;
+
+ Data_Get_Struct(array_val, afstruct, input);
+ Data_Get_Struct(weighted_array_val, afstruct, weighted_array);
+
+ af_err flag = af_mean_all_weighted(&real_part, &imag_part, input->carray, weighted_array->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return DBL2NUM(real_part);
+}
+
+static VALUE arf_var_all(VALUE self, VALUE array_val, VALUE is_biased){
+ afstruct* input;
+ double real_part, imag_part;
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_err flag = af_var_all(&real_part, &imag_part, input->carray, RTEST(is_biased));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return DBL2NUM(real_part);
+}
+
+static VALUE arf_var_all_weighted(VALUE self, VALUE array_val, VALUE weighted_array_val){
+ afstruct* input;
+ afstruct* weighted_array;
+ double real_part, imag_part;
+
+ Data_Get_Struct(array_val, afstruct, input);
+ Data_Get_Struct(weighted_array_val, afstruct, weighted_array);
+
+ af_err flag = af_var_all_weighted(&real_part, &imag_part, input->carray, weighted_array->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return DBL2NUM(real_part);
+}
+
+static VALUE arf_stdev_all(VALUE self, VALUE array_val){
+ afstruct* input;
+ double real_part, imag_part;
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_err flag = af_stdev_all(&real_part, &imag_part, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return DBL2NUM(real_part);
+}
+
+static VALUE arf_median_all(VALUE self, VALUE array_val){
+ afstruct* input;
+ double real_part, imag_part;
+
+ Data_Get_Struct(array_val, afstruct, input);
+
+ af_err flag = af_median_all(&real_part, &imag_part, input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return DBL2NUM(real_part);
+}
+
+static VALUE arf_corrcoef(VALUE self, VALUE first_array_val, VALUE second_array_val){
+ afstruct* first_array;
+ afstruct* second_array;
+ double real_part, imag_part;
+
+ Data_Get_Struct(first_array_val, afstruct, first_array);
+ Data_Get_Struct(first_array_val, afstruct, second_array);
+
+ af_err flag = af_corrcoef(&real_part, &imag_part, first_array->carray, second_array->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return DBL2NUM(real_part);
+}
diff --git a/ext/mri/cmodules/util.c b/ext/mri/cmodules/util.c
new file mode 100644
index 0000000..5e4743d
--- /dev/null
+++ b/ext/mri/cmodules/util.c
@@ -0,0 +1,90 @@
+static VALUE arf_print_array(VALUE self, VALUE input_val){
+ afstruct* input;
+
+ Data_Get_Struct(input_val, afstruct, input);
+
+ af_err flag = af_print_array(input->carray);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return Qtrue;
+}
+
+static VALUE arf_print_array_gen(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_save_array(VALUE self, VALUE key_val, VALUE array_val, VALUE fn_val, VALUE append){
+ afstruct* input;
+
+ Data_Get_Struct(array_val, afstruct, input);
+ const char* key = StringValueCStr(key_val);
+ const char* filename = StringValueCStr(fn_val);
+ int index;
+
+ af_err flag = af_save_array (&index, key, input->carray, filename, RTEST(append));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return INT2NUM(index);
+}
+
+static VALUE arf_read_array_index(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_read_array_key(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_read_array_key_check(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_array_to_string(VALUE self, VALUE exp_val, VALUE array_val, VALUE precision, VALUE transpose){
+ char* output;
+ afstruct* input;
+
+ Data_Get_Struct(array_val, afstruct, input);
+ const char* exp = StringValueCStr(exp_val);
+
+ af_err flag = af_array_to_string(&output, exp, input->carray, NUM2INT(precision), RTEST(transpose));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return rb_str_new_cstr(output);
+}
+
+static VALUE arf_example_function(VALUE self){
+ return Qnil;
+}
+
+static VALUE arf_get_version(VALUE self){
+ int major, minor, patch;
+
+ af_err flag = af_get_version(&major, &minor, &patch);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ VALUE hash = rb_hash_new();
+ rb_hash_aset(hash, rb_str_new_cstr("major"), INT2NUM(major));
+ rb_hash_aset(hash, rb_str_new_cstr("minor"), INT2NUM(minor));
+ rb_hash_aset(hash, rb_str_new_cstr("patch"), INT2NUM(patch));
+
+ return hash;
+}
+
+static VALUE arf_get_revision(VALUE self){
+ const char* revision = af_get_revision();
+ return rb_str_new_cstr(revision);
+}
+
+static VALUE arf_get_size_of(VALUE self, VALUE dtype_val){
+ size_t size;
+
+ af_err flag = af_get_size_of(&size, arf_dtype_from_rbsymbol(dtype_val));
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return ULL2NUM(size);
+}
diff --git a/ext/mri/extconf.rb b/ext/mri/extconf.rb
index 5f2937b..ff26e5c 100644
--- a/ext/mri/extconf.rb
+++ b/ext/mri/extconf.rb
@@ -2,7 +2,9 @@
extension_name = 'arrayfire'
-dir_config(extension_name)
+nmatrix_path = Gem::Specification.find_all_by_name('nmatrix').compact
+abort "Cannot locate NMatrix installation" unless nmatrix_path
+nmatrix_header_dir = File.join(nmatrix_path[0].require_path)
$INSTALLFILES = [
['ruby_arrayfire.h' , '$(archdir)'],
@@ -15,19 +17,36 @@
$CXXFLAGS = ["-Wall -Werror=return-type",$CXXFLAGS].join(" ")
$CPPFLAGS = ["-Wall -Werror=return-type",$CPPFLAGS].join(" ")
-dir_config('arrayfire', '/usr/local/include/', '/usr/local/lib/')
-# $LOCAL_LIBS =
LIBDIR = RbConfig::CONFIG['libdir']
INCLUDEDIR = RbConfig::CONFIG['includedir']
-HEADER_DIRS = [INCLUDEDIR, '/usr/local/include/', '/usr/local/include/af/']
+HEADER_DIRS = [
+ '/opt/local/include',
+ '/usr/local/include',
+ INCLUDEDIR,
+ '/usr/include',
+ nmatrix_header_dir
+]
+
+LIB_DIRS = [
+ '/opt/local/lib',
+ '/usr/local/lib',
+ LIBDIR,
+ '/usr/lib',
+ nmatrix_header_dir
+]
+
+dir_config(extension_name, HEADER_DIRS, LIB_DIRS)
-have_library('afcuda')
+have_library('af')
have_library('cusolver')
have_library('cudart')
have_library('cufft')
have_library('cublas')
+have_library('nmatrix')
+have_header("nmatrix_config.h")
+abort "Cannot locate NMatrix header files : nmatrix.h" unless find_header("nmatrix.h")
basenames = %w{ruby_arrayfire}
$objs = basenames.map { |b| "#{b}.o" }
diff --git a/ext/mri/interfaces/nmatrix.c b/ext/mri/interfaces/nmatrix.c
new file mode 100644
index 0000000..0b016dd
--- /dev/null
+++ b/ext/mri/interfaces/nmatrix.c
@@ -0,0 +1,66 @@
+static VALUE arf_af_array_to_nmatrix(VALUE self) {
+ afstruct* input;
+ Data_Get_Struct(self, afstruct, input);
+ dim_t count;
+ uint ndims;
+
+ af_err flag = af_get_numdims(&ndims, input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ dim_t* dims = ALLOC_N(dim_t, ndims);
+
+ flag = af_get_dims(&dims[0], &dims[1], &dims[2], &dims[3], input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ size_t* shape = ALLOC_N(size_t, ndims);
+ for (dim_t index = 0; index < ndims; index++){
+ shape[index] = (size_t)(dims[index]);
+ }
+
+ flag = af_get_elements(&count, input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ double* elements = ALLOC_N(double, count);
+
+ flag = af_get_data_ptr(elements, input->carray);
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return rb_nmatrix_dense_create(nm::FLOAT64, shape, ndims, elements, (int)count);
+}
+
+extern VALUE arf_nmatrix_to_af_array_method(VALUE nmatrix) {
+ if (NM_DIM(nmatrix) > 4) {
+ rb_raise(rb_eStandardError,
+ "NMatrix must not have greater than 4 dimensions.");
+ }
+
+ if (NM_DTYPE(nmatrix) == nm::FLOAT64) {
+ return Data_Wrap_Struct(Af_Array, NULL, arf_free, arf_nmatrix_to_af_array(nmatrix));
+ }
+ else {
+ rb_raise(rb_eStandardError,
+ "NMatrix should be either :complex64, :complex128, :int32 or :float64 type.");
+ }
+ return Qnil;
+}
+
+
+afstruct* arf_nmatrix_to_af_array(VALUE nm) {
+ DENSE_STORAGE* nmat = NM_STORAGE_DENSE(nm);
+ afstruct* output = ALLOC(afstruct);
+
+ if (nmat->dtype != nm::FLOAT64) {
+ rb_raise(rb_eStandardError, "requires dtype of :float64 to convert to an Af_Array");
+ }
+
+ dim_t* shape = ALLOC_N(dim_t, nmat->dim);
+ for (size_t index = 0; index < nmat->dim; index++){
+ shape[index] = (size_t)(nmat->shape[index]);
+ }
+
+ af_err flag = af_create_array(&output->carray, nmat->elements, nmat->dim, shape, f64);
+
+ if (flag != AF_SUCCESS) arf_handle_exception(flag);
+
+ return output;
+}
diff --git a/ext/mri/ruby_arrayfire.cpp b/ext/mri/ruby_arrayfire.cpp
index a94666c..4b16065 100644
--- a/ext/mri/ruby_arrayfire.cpp
+++ b/ext/mri/ruby_arrayfire.cpp
@@ -2,8 +2,14 @@
#include // std::min
#include
#include
+#include
+#include
#include
#include
+#include