[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