[DRE-commits] [ruby-mpi] 01/03: Imported Upstream version 0.3.0

Youhei SASAKI uwabami-guest at moszumanska.debian.org
Wed Jul 9 09:23:00 UTC 2014


This is an automated email from the git hooks/post-receive script.

uwabami-guest pushed a commit to branch master
in repository ruby-mpi.

commit f0ccb12e896d46f7d5b206ed420f63e313b9d5d2
Author: Youhei SASAKI <uwabami at gfd-dennou.org>
Date:   Wed Jun 25 20:44:26 2014 +0900

    Imported Upstream version 0.3.0
---
 Gemfile                  |   8 +-
 Gemfile.lock             |  30 -------
 LICENSE.txt              |   2 +-
 README.rdoc              |   7 +-
 Rakefile                 |   3 +-
 VERSION                  |   2 +-
 checksums.yaml.gz        | Bin 0 -> 270 bytes
 ext/mpi/extconf.rb       |  14 +++-
 ext/mpi/mpi.c            | 212 +++++++++++++++++++++++++++++++----------------
 lib/mpi/utils.rb         |  17 ++++
 metadata.yml             | 159 ++++++++++++++++++-----------------
 samples/hello.rb         |   8 +-
 samples/narray.rb        |   6 ++
 samples/narray_offset.rb |  29 +++++++
 spec/ruby-mpi_spec.rb    |   8 +-
 test/test_utils.rb       |  21 +++++
 16 files changed, 329 insertions(+), 197 deletions(-)

diff --git a/Gemfile b/Gemfile
index 6c3f1da..4891e03 100644
--- a/Gemfile
+++ b/Gemfile
@@ -6,9 +6,9 @@ source "http://rubygems.org"
 # Add dependencies to develop your gem here.
 # Include everything needed to run rake, tests, features, etc.
 group :development do
-  gem "rspec", "~> 2.3.0"
-  gem "bundler", "~> 1.0.0"
-  gem "jeweler", "~> 1.5.2"
-  gem "rcov", ">= 0"
+  gem "rspec", ">= 2.3.0"
+  gem "bundler", ">= 1.0.0"
+  gem "jeweler", ">= 1.5.2"
+  gem "simplecov", ">= 0"
   gem "narray", ">= 0"
 end
diff --git a/Gemfile.lock b/Gemfile.lock
deleted file mode 100644
index a5d36f3..0000000
--- a/Gemfile.lock
+++ /dev/null
@@ -1,30 +0,0 @@
-GEM
-  remote: http://rubygems.org/
-  specs:
-    diff-lcs (1.1.2)
-    git (1.2.5)
-    jeweler (1.5.2)
-      bundler (~> 1.0.0)
-      git (>= 1.2.5)
-      rake
-    narray (0.5.9.9)
-    rake (0.8.7)
-    rcov (0.9.9)
-    rspec (2.3.0)
-      rspec-core (~> 2.3.0)
-      rspec-expectations (~> 2.3.0)
-      rspec-mocks (~> 2.3.0)
-    rspec-core (2.3.1)
-    rspec-expectations (2.3.0)
-      diff-lcs (~> 1.1.2)
-    rspec-mocks (2.3.0)
-
-PLATFORMS
-  ruby
-
-DEPENDENCIES
-  bundler (~> 1.0.0)
-  jeweler (~> 1.5.2)
-  narray
-  rcov
-  rspec (~> 2.3.0)
diff --git a/LICENSE.txt b/LICENSE.txt
index 14f7acc..86136c3 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2011 Seiya Nishizawa
+Copyright (c) 2011-2012 Seiya Nishizawa
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
diff --git a/README.rdoc b/README.rdoc
index 282a177..1d527aa 100644
--- a/README.rdoc
+++ b/README.rdoc
@@ -5,6 +5,11 @@ Ruby-MPI is a ruby binding of Message Passing Interface (MPI), which is an API s
 == Install
 
  # gem install ruby-mpi
+ 
+== How to run
+Use mpirun or mpiexec to run a script
+e.g. (run with 4 processes)
+ # mpirun -np 4 ruby hello.rb
 
 == Contributing to Ruby-MPI
  
@@ -18,6 +23,6 @@ Ruby-MPI is a ruby binding of Message Passing Interface (MPI), which is an API s
 
 == Copyright
 
-Copyright (c) 2011 Seiya Nishizawa. See LICENSE.txt for
+Copyright (c) 2011-2012 Seiya Nishizawa. See LICENSE.txt for
 further details.
 
diff --git a/Rakefile b/Rakefile
index 85ce1b2..99bd66f 100644
--- a/Rakefile
+++ b/Rakefile
@@ -40,7 +40,7 @@ end
 
 task :default => :spec
 
-require 'rake/rdoctask'
+require 'rdoc/task'
 Rake::RDocTask.new do |rdoc|
   version = File.exist?('VERSION') ? File.read('VERSION') : ""
 
@@ -48,6 +48,7 @@ Rake::RDocTask.new do |rdoc|
   rdoc.title = "ruby-mpi #{version}"
   rdoc.rdoc_files.include('README*')
   rdoc.rdoc_files.include('lib/**/*.rb')
+  rdoc.rdoc_files.include('samples/*.rb')
 end
 
 
diff --git a/VERSION b/VERSION
index 341cf11..0d91a54 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.2.0
\ No newline at end of file
+0.3.0
diff --git a/checksums.yaml.gz b/checksums.yaml.gz
new file mode 100644
index 0000000..12a9fa0
Binary files /dev/null and b/checksums.yaml.gz differ
diff --git a/ext/mpi/extconf.rb b/ext/mpi/extconf.rb
index 42eddea..4320394 100644
--- a/ext/mpi/extconf.rb
+++ b/ext/mpi/extconf.rb
@@ -4,12 +4,20 @@ CONFIG['CC'] = "mpicc"
 gem_path = nil
 begin
   require "rubygems"
-  if (spec = Gem.source_index.find_name("narray")).any?
-    gem_path = spec.last.full_gem_path
+  if Gem::Specification.respond_to?(:find_by_name)
+    if spec = Gem::Specification.find_by_name("narray")
+      gem_path = spec.full_gem_path
+    end
+  else
+    if (spec = Gem.source_index.find_name("narray")).any?
+      gem_path = spec.full_gem_path
+    end
   end
 rescue LoadError
   dir_config("narray", Config::CONFIG["sitearchdir"])
 end
-find_header("narray.h", gem_path)
+unless find_header("narray.h", gem_path)
+  find_header("narray.h", File.join(gem_path,"src"))
+end
 
 create_makefile("mpi")
diff --git a/ext/mpi/mpi.c b/ext/mpi/mpi.c
index ba7cb36..e54d3d0 100644
--- a/ext/mpi/mpi.c
+++ b/ext/mpi/mpi.c
@@ -6,38 +6,45 @@
 #include "mpi.h"
 
 
-#define OBJ2C(rb_obj, len, buffer, typ) \
+#define OBJ2C(rb_obj, len, buffer, typ, off) \
 {\
   if (TYPE(rb_obj) == T_STRING) {\
-    len = RSTRING_LEN(rb_obj);\
-    buffer = (void*)StringValuePtr(rb_obj);\
-    typ = MPI_CHAR;\
-  } else if (IsNArray(rb_obj)) {		\
+    if (len==0) len = RSTRING_LEN(rb_obj);\
+    buffer = (void*)(StringValuePtr(rb_obj) + off);\
+    typ = MPI_BYTE;\
+  } else if (IsNArray(rb_obj)) {\
     struct NARRAY *a;\
     GetNArray(rb_obj, a);\
     buffer = (void*)(a->ptr);\
-    len = a->total;\
+    if (len==0) len = a->total;\
     switch (a->type) {\
     case NA_BYTE:\
       typ = MPI_BYTE;\
+      buffer = (void*)((char*)buffer + off);\
       break;\
     case NA_SINT:\
       typ = MPI_SHORT;\
+      buffer = (void*)((char*)buffer + off*4);\
       break;\
     case NA_LINT:\
       typ = MPI_LONG;\
+      buffer = (void*)((char*)buffer + off*8);\
       break;\
     case NA_SFLOAT:\
       typ = MPI_FLOAT;\
+      buffer = (void*)((char*)buffer + off*4);\
       break;\
     case NA_DFLOAT:\
       typ = MPI_DOUBLE;\
+      buffer = (void*)((char*)buffer + off*8);\
       break;\
     case NA_SCOMPLEX:\
       typ = MPI_2COMPLEX;\
+      buffer = (void*)((char*)buffer + off*8);\
       break;\
     case NA_DCOMPLEX:\
       typ = MPI_2DOUBLE_COMPLEX;\
+      buffer = (void*)((char*)buffer + off*16);\
       break;\
     default:\
       rb_raise(rb_eArgError, "narray type is invalid");\
@@ -54,48 +61,36 @@ static VALUE eBUFFER, eCOUNT, eTYPE, eTAG, eCOMM, eRANK, eREQUEST, eROOT, eGROUP
 
 struct _Comm {
   MPI_Comm Comm;
+  bool free;
 };
 struct _Request {
   MPI_Request Request;
+  bool free;
 };
 struct _Op {
   MPI_Op Op;
+  bool free;
 };
 struct _Errhandler {
   MPI_Errhandler Errhandler;
+  bool free;
 };
 
 static bool _initialized = false;
 static bool _finalized = false;
 
 
-#define DEF_FREE(name) \
-static void \
-name ## _free(void *ptr)\
-{\
-  struct _ ## name *obj;\
-  obj = (struct _ ## name*) ptr;\
-  if (!_finalized)\
-    MPI_ ## name ## _free(&(obj->name)); \
-  free(obj);\
-}
-DEF_FREE(Comm)
-DEF_FREE(Request)
-DEF_FREE(Op)
-DEF_FREE(Errhandler)
-static void
-Status_free(void *ptr)
-{
-  free((MPI_Status*) ptr);
-}
-
-
-#define CAE_ERR(type) case MPI_ERR_ ## type: rb_raise(e ## type,""); break
+#define CAE_ERR(type) case MPI_ERR_ ## type: rb_raise(e ## type,"%s",str); break
 static void
 check_error(int error)
 {
-  switch (error) {
-  case MPI_SUCCESS: break;
+  if (error == MPI_SUCCESS) return;
+  int code, len;
+  char str[MPI_MAX_ERROR_STRING];
+  if (MPI_Error_class(error, &code)!=MPI_SUCCESS || MPI_Error_string(error, str, &len)!=MPI_SUCCESS)
+    rb_raise(rb_eRuntimeError, "unknown error occuerd in MPI call");
+
+  switch (code) {
     CAE_ERR(BUFFER);
     CAE_ERR(COUNT);
     CAE_ERR(TYPE);
@@ -154,15 +149,48 @@ check_error(int error)
     CAE_ERR(SYSRESOURCE);
 #endif
   default:
-    rb_raise(rb_eRuntimeError, "unknown error");
+    rb_raise(rb_eRuntimeError, "unknown error: %d", code);
   }
 }
 
+#define DEF_FREE(name, capit)				\
+static void \
+name ## _free(void *ptr)\
+{\
+  struct _ ## name *obj;\
+  obj = (struct _ ## name*) ptr;\
+  if (!_finalized && obj->free && obj->name!=MPI_ ## capit ##_NULL)\
+    check_error(MPI_ ## name ## _free(&(obj->name))); \
+  free(obj);\
+}
+#define DEF_FREE2(name, capit)				\
+static void \
+name ## _free2(void *ptr)\
+{\
+  struct _ ## name *obj;\
+  obj = (struct _ ## name*) ptr;\
+  free(obj);\
+}
+DEF_FREE(Comm, COMM)
+DEF_FREE(Request, REQUEST)
+DEF_FREE(Op, OP)
+DEF_FREE(Errhandler, ERRHANDLER)
+DEF_FREE2(Comm, COMM)
+DEF_FREE2(Op, OP)
+DEF_FREE2(Errhandler, ERRHANDLER)
+static void
+Status_free(void *ptr)
+{
+  free((MPI_Status*) ptr);
+}
+
+
 #define DEF_CONST(v, const, name) \
 {\
   v = ALLOC(struct _ ## v);\
   v->v = const;\
-  rb_define_const(c ## v, #name, Data_Wrap_Struct(c ## v, NULL, v ## _free, v));	\
+  v->free = false;\
+  rb_define_const(c ## v, #name, Data_Wrap_Struct(c ## v, NULL, v ## _free2, v));	\
 }
 
 static void
@@ -216,7 +244,7 @@ rb_m_init(int argc, VALUE *argv, VALUE self)
   // define MPI::Comm::WORLD
   struct _Comm *Comm;
   DEF_CONST(Comm, MPI_COMM_WORLD, WORLD);
-  MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
+  check_error(MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN));
 
   // define MPI::Op::???
   struct _Op *Op;
@@ -249,6 +277,16 @@ rb_m_finalize(VALUE self)
   return self;
 }
 
+static VALUE
+rb_m_abort(VALUE self, VALUE rcomm, VALUE rerror)
+{
+  struct _Comm *comm;
+  int ierror;
+  Data_Get_Struct(rcomm, struct _Comm, comm);
+  ierror = MPI_Abort(comm->Comm, NUM2INT(rerror));
+  return INT2NUM(ierror);
+}
+
 
 // MPI::Comm
 static VALUE
@@ -262,6 +300,7 @@ rb_comm_initialize(VALUE self)
 {
   rb_raise(rb_eRuntimeError, "not developed yet");
   // MPI_Comm_create()
+  // comm->free = true;
 }
 static VALUE
 rb_comm_size(VALUE self)
@@ -285,11 +324,11 @@ static VALUE
 rb_comm_send(VALUE self, VALUE rb_obj, VALUE rb_dest, VALUE rb_tag)
 {
   void* buffer;
-  int len, dest, tag;
+  int len=0, dest, tag;
   MPI_Datatype type;
   struct _Comm *comm;
 
-  OBJ2C(rb_obj, len, buffer, type);
+  OBJ2C(rb_obj, len, buffer, type, 0);
   dest = NUM2INT(rb_dest);
   tag = NUM2INT(rb_tag);
   Data_Get_Struct(self, struct _Comm, comm);
@@ -301,31 +340,43 @@ static VALUE
 rb_comm_isend(VALUE self, VALUE rb_obj, VALUE rb_dest, VALUE rb_tag)
 {
   void* buffer;
-  int len, dest, tag;
+  int len=0, dest, tag;
   MPI_Datatype type;
   struct _Comm *comm;
   struct _Request *request;
   VALUE rb_request;
 
-  OBJ2C(rb_obj, len, buffer, type);
+  OBJ2C(rb_obj, len, buffer, type, 0);
   dest = NUM2INT(rb_dest);
   tag = NUM2INT(rb_tag);
   Data_Get_Struct(self, struct _Comm, comm);
   rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
+  request->free = true;
   check_error(MPI_Isend(buffer, len, type, dest, tag, comm->Comm, &(request->Request)));
 
   return rb_request;
 }
 static VALUE
-rb_comm_recv(VALUE self, VALUE rb_obj, VALUE rb_source, VALUE rb_tag)
+rb_comm_recv(int argc, VALUE *argv, VALUE self)
 {
+  VALUE rb_obj, rb_source, rb_tag;
+  VALUE rb_len, rb_offset; // option
   void* buffer;
-  int len, source, tag;
+  int source, tag, len = 0, offset = 0;
   MPI_Datatype type;
   MPI_Status *status;
   struct _Comm *comm;
 
-  OBJ2C(rb_obj, len, buffer, type);
+  rb_scan_args(argc, argv, "32", &rb_obj, &rb_source, &rb_tag, &rb_len, &rb_offset);
+
+  if (rb_len != Qnil) {
+    len = NUM2INT(rb_len);
+  }
+  if (rb_offset != Qnil) {
+    offset = NUM2INT(rb_offset);
+  }
+
+  OBJ2C(rb_obj, len, buffer, type, offset);
   source = NUM2INT(rb_source);
   tag = NUM2INT(rb_tag);
 
@@ -336,20 +387,33 @@ rb_comm_recv(VALUE self, VALUE rb_obj, VALUE rb_source, VALUE rb_tag)
   return Data_Wrap_Struct(cStatus, NULL, Status_free, status);
 }
 static VALUE
-rb_comm_irecv(VALUE self, VALUE rb_obj, VALUE rb_source, VALUE rb_tag)
+rb_comm_irecv(int argc, VALUE *argv, VALUE self)
 {
+  VALUE rb_obj, rb_source, rb_tag;
+  VALUE rb_len, rb_offset; // option
   void* buffer;
-  int len, source, tag;
+  int source, tag, len = 0, offset = 0;
   MPI_Datatype type;
   struct _Comm *comm;
   struct _Request *request;
   VALUE rb_request;
 
-  OBJ2C(rb_obj, len, buffer, type);
+  rb_scan_args(argc, argv, "32", &rb_obj, &rb_source, &rb_tag, &rb_len, &rb_offset);
+
+  if (rb_len != Qnil) {
+    len = NUM2INT(rb_len);
+  }
+  if (rb_offset != Qnil) {
+    offset = NUM2INT(rb_offset);
+  }
+
+  OBJ2C(rb_obj, len, buffer, type, offset);
   source = NUM2INT(rb_source);
   tag = NUM2INT(rb_tag);
+
   Data_Get_Struct(self, struct _Comm, comm);
   rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
+  request->free = true;
   check_error(MPI_Irecv(buffer, len, type, source, tag, comm->Comm, &(request->Request)));
 
   return rb_request;
@@ -358,17 +422,17 @@ static VALUE
 rb_comm_gather(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_root)
 {
   void *sendbuf, *recvbuf = NULL;
-  int sendcount, recvcount = 0;
-  MPI_Datatype sendtype, recvtype = NULL;
+  int sendcount=0, recvcount = 0;
+  MPI_Datatype sendtype, recvtype = 0;
   int root, rank, size;
   struct _Comm *comm;
-  OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype);
+  OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
   root = NUM2INT(rb_root);
   Data_Get_Struct(self, struct _Comm, comm);
   check_error(MPI_Comm_rank(comm->Comm, &rank));
   check_error(MPI_Comm_size(comm->Comm, &size));
   if (rank == root) {
-    OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype);
+    OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
     if (recvcount < sendcount*size)
       rb_raise(rb_eArgError, "recvbuf is too small");
     recvcount = sendcount;
@@ -380,15 +444,15 @@ static VALUE
 rb_comm_allgather(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf)
 {
   void *sendbuf, *recvbuf;
-  int sendcount, recvcount;
+  int sendcount=0, recvcount=0;
   MPI_Datatype sendtype, recvtype;
   int rank, size;
   struct _Comm *comm;
-  OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype);
+  OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
   Data_Get_Struct(self, struct _Comm, comm);
   check_error(MPI_Comm_rank(comm->Comm, &rank));
   check_error(MPI_Comm_size(comm->Comm, &size));
-  OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype);
+  OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
   if (recvcount < sendcount*size)
     rb_raise(rb_eArgError, "recvbuf is too small");
   recvcount = sendcount;
@@ -399,11 +463,11 @@ static VALUE
 rb_comm_bcast(VALUE self, VALUE rb_buffer, VALUE rb_root)
 {
   void *buffer;
-  int count;
+  int count=0;
   MPI_Datatype type;
   int root;
   struct _Comm *comm;
-  OBJ2C(rb_buffer, count, buffer, type);
+  OBJ2C(rb_buffer, count, buffer, type, 0);
   root = NUM2INT(rb_root);
   Data_Get_Struct(self, struct _Comm, comm);
   check_error(MPI_Bcast(buffer, count, type, root, comm->Comm));
@@ -413,17 +477,17 @@ static VALUE
 rb_comm_scatter(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_root)
 {
   void *sendbuf = NULL, *recvbuf;
-  int sendcount = 0, recvcount;
-  MPI_Datatype sendtype = NULL, recvtype;
+  int sendcount = 0, recvcount=0;
+  MPI_Datatype sendtype = 0, recvtype;
   int root, rank, size;
   struct _Comm *comm;
-  OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype);
+  OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
   root = NUM2INT(rb_root);
   Data_Get_Struct(self, struct _Comm, comm);
   check_error(MPI_Comm_rank(comm->Comm, &rank));
   check_error(MPI_Comm_size(comm->Comm, &size));
   if (rank == root) {
-    OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype);
+    OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
     if (sendcount > recvcount*size)
       rb_raise(rb_eArgError, "recvbuf is too small");
     sendcount = recvcount;
@@ -435,17 +499,17 @@ static VALUE
 rb_comm_sendrecv(VALUE self, VALUE rb_sendbuf, VALUE rb_dest, VALUE rb_sendtag, VALUE rb_recvbuf, VALUE rb_source, VALUE rb_recvtag)
 {
   void *sendbuf, *recvbuf;
-  int sendcount, recvcount;
+  int sendcount=0, recvcount=0;
   MPI_Datatype sendtype, recvtype;
   int dest, source;
   int sendtag, recvtag;
   int size;
   struct _Comm *comm;
   MPI_Status *status;
-  OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype);
+  OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
   Data_Get_Struct(self, struct _Comm, comm);
   check_error(MPI_Comm_size(comm->Comm, &size));
-  OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype);
+  OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
   dest = NUM2INT(rb_dest);
   source = NUM2INT(rb_source);
   sendtag = NUM2INT(rb_sendtag);
@@ -458,14 +522,14 @@ static VALUE
 rb_comm_alltoall(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf)
 {
   void *sendbuf, *recvbuf;
-  int sendcount, recvcount;
+  int sendcount=0, recvcount=0;
   MPI_Datatype sendtype, recvtype;
   int size;
   struct _Comm *comm;
-  OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype);
+  OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
   Data_Get_Struct(self, struct _Comm, comm);
   check_error(MPI_Comm_size(comm->Comm, &size));
-  OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype);
+  OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
   if (recvcount < sendcount)
     rb_raise(rb_eArgError, "recvbuf is too small");
   recvcount = recvcount/size;
@@ -477,18 +541,18 @@ static VALUE
 rb_comm_reduce(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op, VALUE rb_root)
 {
   void *sendbuf, *recvbuf = NULL;
-  int sendcount, recvcount = 0;
-  MPI_Datatype sendtype, recvtype = NULL;
+  int sendcount=0, recvcount = 0;
+  MPI_Datatype sendtype, recvtype = 0;
   int root, rank, size;
   struct _Comm *comm;
   struct _Op *op;
-  OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype);
+  OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
   root = NUM2INT(rb_root);
   Data_Get_Struct(self, struct _Comm, comm);
   check_error(MPI_Comm_rank(comm->Comm, &rank));
   check_error(MPI_Comm_size(comm->Comm, &size));
   if (rank == root) {
-    OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype);
+    OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
     if (recvcount != sendcount)
       rb_raise(rb_eArgError, "sendbuf and recvbuf has the same length");
     if (recvtype != sendtype)
@@ -502,16 +566,16 @@ static VALUE
 rb_comm_allreduce(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
 {
   void *sendbuf, *recvbuf;
-  int sendcount, recvcount;
+  int sendcount=0, recvcount=0;
   MPI_Datatype sendtype, recvtype;
   int rank, size;
   struct _Comm *comm;
   struct _Op *op;
-  OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype);
+  OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
   Data_Get_Struct(self, struct _Comm, comm);
   check_error(MPI_Comm_rank(comm->Comm, &rank));
   check_error(MPI_Comm_size(comm->Comm, &size));
-  OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype);
+  OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
   if (recvcount != sendcount)
     rb_raise(rb_eArgError, "sendbuf and recvbuf has the same length");
   if (recvtype != sendtype)
@@ -529,7 +593,8 @@ rb_comm_get_Errhandler(VALUE self)
 
   Data_Get_Struct(self, struct _Comm, comm);
   rb_errhandler = Data_Make_Struct(cErrhandler, struct _Errhandler, NULL, Errhandler_free, errhandler);
-  MPI_Comm_get_errhandler(comm->Comm, &(errhandler->Errhandler));
+  errhandler->free = false;
+  check_error(MPI_Comm_get_errhandler(comm->Comm, &(errhandler->Errhandler)));
   return rb_errhandler;
 }
 static VALUE
@@ -540,7 +605,7 @@ rb_comm_set_Errhandler(VALUE self, VALUE rb_errhandler)
 
   Data_Get_Struct(self, struct _Comm, comm);
   Data_Get_Struct(rb_errhandler, struct _Errhandler, errhandler);
-  MPI_Comm_set_errhandler(comm->Comm, errhandler->Errhandler);
+  check_error(MPI_Comm_set_errhandler(comm->Comm, errhandler->Errhandler));
   return self;
 }
 static VALUE
@@ -607,6 +672,7 @@ void Init_mpi()
   mMPI = rb_define_module("MPI");
   rb_define_module_function(mMPI, "Init", rb_m_init, -1);
   rb_define_module_function(mMPI, "Finalize", rb_m_finalize, -1);
+  rb_define_module_function(mMPI, "Abort", rb_m_abort, 2);
   rb_define_const(mMPI, "VERSION", INT2NUM(MPI_VERSION));
   rb_define_const(mMPI, "SUBVERSION", INT2NUM(MPI_SUBVERSION));
   rb_define_const(mMPI, "SUCCESS", INT2NUM(MPI_SUCCESS));
@@ -620,8 +686,8 @@ void Init_mpi()
   rb_define_method(cComm, "size", rb_comm_size, 0);
   rb_define_method(cComm, "Send", rb_comm_send, 3);
   rb_define_method(cComm, "Isend", rb_comm_isend, 3);
-  rb_define_method(cComm, "Recv", rb_comm_recv, 3);
-  rb_define_method(cComm, "Irecv", rb_comm_irecv, 3);
+  rb_define_method(cComm, "Recv", rb_comm_recv, -1);
+  rb_define_method(cComm, "Irecv", rb_comm_irecv, -1);
   rb_define_method(cComm, "Gather", rb_comm_gather, 3);
   rb_define_method(cComm, "Allgather", rb_comm_allgather, 2);
   rb_define_method(cComm, "Bcast", rb_comm_bcast, 2);
diff --git a/lib/mpi/utils.rb b/lib/mpi/utils.rb
new file mode 100644
index 0000000..cd120e6
--- /dev/null
+++ b/lib/mpi/utils.rb
@@ -0,0 +1,17 @@
+module MPI
+
+  module_function
+
+  def task_divide(m, size)
+    dm = m.to_f/size
+    ary = Array.new(size)
+    ary[0] = dm.round
+    sum = ary[0]
+    (size-1).times do|i|
+      ary[i+1] = (dm*(i+2)).round - sum
+      sum += ary[i+1]
+    end
+    ary
+  end
+
+end # module MPI
diff --git a/metadata.yml b/metadata.yml
index 84c9541..d687029 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -1,86 +1,98 @@
---- !ruby/object:Gem::Specification 
+--- !ruby/object:Gem::Specification
 name: ruby-mpi
-version: !ruby/object:Gem::Version 
-  prerelease: 
-  version: 0.2.0
+version: !ruby/object:Gem::Version
+  version: 0.3.0
 platform: ruby
-authors: 
+authors:
 - Seiya Nishizawa
 autorequire: 
 bindir: bin
 cert_chain: []
-
-date: 2011-04-22 00:00:00 Z
-dependencies: 
-- !ruby/object:Gem::Dependency 
+date: 2014-05-23 00:00:00.000000000 Z
+dependencies:
+- !ruby/object:Gem::Dependency
   name: rspec
-  requirement: &id001 !ruby/object:Gem::Requirement 
-    none: false
-    requirements: 
-    - - ~>
-      - !ruby/object:Gem::Version 
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - '>='
+      - !ruby/object:Gem::Version
         version: 2.3.0
   type: :development
   prerelease: false
-  version_requirements: *id001
-- !ruby/object:Gem::Dependency 
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - '>='
+      - !ruby/object:Gem::Version
+        version: 2.3.0
+- !ruby/object:Gem::Dependency
   name: bundler
-  requirement: &id002 !ruby/object:Gem::Requirement 
-    none: false
-    requirements: 
-    - - ~>
-      - !ruby/object:Gem::Version 
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - '>='
+      - !ruby/object:Gem::Version
         version: 1.0.0
   type: :development
   prerelease: false
-  version_requirements: *id002
-- !ruby/object:Gem::Dependency 
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - '>='
+      - !ruby/object:Gem::Version
+        version: 1.0.0
+- !ruby/object:Gem::Dependency
   name: jeweler
-  requirement: &id003 !ruby/object:Gem::Requirement 
-    none: false
-    requirements: 
-    - - ~>
-      - !ruby/object:Gem::Version 
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - '>='
+      - !ruby/object:Gem::Version
         version: 1.5.2
   type: :development
   prerelease: false
-  version_requirements: *id003
-- !ruby/object:Gem::Dependency 
-  name: rcov
-  requirement: &id004 !ruby/object:Gem::Requirement 
-    none: false
-    requirements: 
-    - - ">="
-      - !ruby/object:Gem::Version 
-        version: "0"
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - '>='
+      - !ruby/object:Gem::Version
+        version: 1.5.2
+- !ruby/object:Gem::Dependency
+  name: simplecov
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - '>='
+      - !ruby/object:Gem::Version
+        version: '0'
   type: :development
   prerelease: false
-  version_requirements: *id004
-- !ruby/object:Gem::Dependency 
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
   name: narray
-  requirement: &id005 !ruby/object:Gem::Requirement 
-    none: false
-    requirements: 
-    - - ">="
-      - !ruby/object:Gem::Version 
-        version: "0"
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - '>='
+      - !ruby/object:Gem::Version
+        version: '0'
   type: :development
   prerelease: false
-  version_requirements: *id005
-description: A ruby binding of Message Passing Interface (MPI), which is an API specification that allows processes to communicate with one another by sending and receiving messages.
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+description: A ruby binding of Message Passing Interface (MPI), which is an API specification
+  that allows processes to communicate with one another by sending and receiving messages.
 email: seiya at gfd-dennou.org
 executables: []
-
-extensions: 
+extensions:
 - ext/mpi/extconf.rb
-extra_rdoc_files: 
+extra_rdoc_files:
 - LICENSE.txt
 - README.rdoc
-files: 
+files:
 - .document
 - .rspec
 - Gemfile
-- Gemfile.lock
 - LICENSE.txt
 - README.rdoc
 - Rakefile
@@ -88,41 +100,36 @@ files:
 - ext/mpi/extconf.rb
 - ext/mpi/mpi.c
 - lib/mpi.rb
+- lib/mpi/utils.rb
 - ruby-mpi.gemspec
 - samples/hello.rb
 - samples/narray.rb
+- samples/narray_offset.rb
 - spec/ruby-mpi_spec.rb
 - spec/spec_helper.rb
+- test/test_utils.rb
 homepage: http://github.com/seiya/ruby-mpi
-licenses: 
+licenses:
 - MIT
+metadata: {}
 post_install_message: 
 rdoc_options: []
-
-require_paths: 
+require_paths:
 - lib
-required_ruby_version: !ruby/object:Gem::Requirement 
-  none: false
-  requirements: 
-  - - ">="
-    - !ruby/object:Gem::Version 
-      hash: -3549605766415082841
-      segments: 
-      - 0
-      version: "0"
-required_rubygems_version: !ruby/object:Gem::Requirement 
-  none: false
-  requirements: 
-  - - ">="
-    - !ruby/object:Gem::Version 
-      version: "0"
+required_ruby_version: !ruby/object:Gem::Requirement
+  requirements:
+  - - '>='
+    - !ruby/object:Gem::Version
+      version: '0'
+required_rubygems_version: !ruby/object:Gem::Requirement
+  requirements:
+  - - '>='
+    - !ruby/object:Gem::Version
+      version: '0'
 requirements: []
-
 rubyforge_project: 
-rubygems_version: 1.7.2
+rubygems_version: 2.1.11
 signing_key: 
-specification_version: 3
+specification_version: 4
 summary: A ruby binding of MPI
-test_files: 
-- spec/ruby-mpi_spec.rb
-- spec/spec_helper.rb
+test_files: []
diff --git a/samples/hello.rb b/samples/hello.rb
index dd3b824..af9fa1d 100644
--- a/samples/hello.rb
+++ b/samples/hello.rb
@@ -4,13 +4,19 @@ MPI.Init
 
 
 world = MPI::Comm::WORLD
+
+if world.size == 1
+  print "Size is one, so do nothing\n"
+  exit
+end
+
 rank = world.rank
 
 if rank == 0
   (world.size-1).times do |i|
     str ="\x00"*100
     world.Recv(str, i+1, 0) 
-    p str
+    p str.gsub(/\000/,"")
   end
 else
   message = "Hello from #{rank}"
diff --git a/samples/narray.rb b/samples/narray.rb
index 0a7682f..a9d3ac5 100644
--- a/samples/narray.rb
+++ b/samples/narray.rb
@@ -4,6 +4,12 @@ MPI.Init
 
 
 world = MPI::Comm::WORLD
+
+if world.size == 1
+  print "Size is one, so do nothing\n"
+  exit
+end
+
 rank = world.rank
 
 if rank == 0
diff --git a/samples/narray_offset.rb b/samples/narray_offset.rb
new file mode 100644
index 0000000..211e879
--- /dev/null
+++ b/samples/narray_offset.rb
@@ -0,0 +1,29 @@
+require "mpi"
+
+MPI.Init
+
+
+world = MPI::Comm::WORLD
+
+if world.size == 1
+  print "Size is one, so do nothing\n"
+  exit
+end
+
+rank = world.rank
+size = world.size
+
+length = 2
+if rank == 0
+  a = NArray.float(length,size-1)
+  (size-1).times do |i|
+    world.Recv(a, i+1, 1, length, i*length)
+  end
+  p a
+else
+  a = NArray.float(length).indgen + rank*10
+  world.Send(a, 0, 1)
+end
+
+
+MPI.Finalize
diff --git a/spec/ruby-mpi_spec.rb b/spec/ruby-mpi_spec.rb
index b9e9170..c194500 100644
--- a/spec/ruby-mpi_spec.rb
+++ b/spec/ruby-mpi_spec.rb
@@ -34,14 +34,13 @@ describe "MPI" do
         status = @world.Recv(str, i+1, tag)
         status.source.should eql(i+1)
         status.tag.should eql(tag)
-        status.error.should eq(MPI::SUCCESS)
         str.should match(/\AHello from #{i+1}/)
       end
     end
   end
 
   it "should send and receive NArray" do
-    tag = 0
+    tag = 1
     rank = @world.rank
     [NArray[1,2,3], NArray[3.0,2.0,1.0]].each do |ary0|
       ary0 = NArray[1,2,3]
@@ -52,7 +51,6 @@ describe "MPI" do
           status = @world.Recv(ary1, i+1, tag)
           status.source.should eql(i+1)
           status.tag.should eql(tag)
-          status.error.should eq(MPI::SUCCESS)
           ary1.should == ary0
         end
       end
@@ -60,14 +58,12 @@ describe "MPI" do
   end
 
   it "should send and receive without blocking" do
-    tag = 0
+    tag = 2
     rank = @world.rank
     message = "Hello from #{rank}"
     if rank != 0
       request = @world.Isend(message, 0, tag)
       status = request.Wait
-#      status.source.should eql(rank)
-      status.tag.should eql(tag)
     end
     if rank == 0
       (@world.size-1).times do |i|
diff --git a/test/test_utils.rb b/test/test_utils.rb
new file mode 100644
index 0000000..c8785d1
--- /dev/null
+++ b/test/test_utils.rb
@@ -0,0 +1,21 @@
+require "test/unit"
+
+$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
+require "mpi/utils"
+
+class TestMPIUtils < Test::Unit::TestCase
+
+  def setup
+  end
+
+  def teardown
+  end
+
+  def test_task_divide
+    [[4,1], [6,3], [7,3], [15,4], [3, 7]].each do |m, size|
+      ary = MPI.task_divide(m, size)
+      assert ary.max-ary.min <= 1
+    end
+  end
+
+end

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-mpi.git



More information about the Pkg-ruby-extras-commits mailing list