ruby-mpi 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/LICENSE.txt +1 -1
- data/README.rdoc +3 -4
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/ext/mpi/mpi.c +800 -7
- data/ruby-mpi.gemspec +30 -35
- data/samples/kmeans.rb +137 -0
- data/samples/pi.rb +59 -0
- data/spec/ruby-mpi_spec.rb +407 -14
- metadata +6 -5
data/ext/mpi/mpi.c
CHANGED
@@ -27,6 +27,10 @@
|
|
27
27
|
---->> Please define NA_MPI_LLINT manually because sizeof(long long) != 8. <<----
|
28
28
|
#endif
|
29
29
|
|
30
|
+
#ifndef NARRAY_BIGMEM
|
31
|
+
# define NA_LLINT -999
|
32
|
+
#endif
|
33
|
+
|
30
34
|
|
31
35
|
#define OBJ2C(rb_obj, len, buffer, typ, off) \
|
32
36
|
{\
|
@@ -313,6 +317,37 @@ rb_m_abort(VALUE self, VALUE rcomm, VALUE rerror)
|
|
313
317
|
return INT2NUM(ierror);
|
314
318
|
}
|
315
319
|
|
320
|
+
static VALUE
|
321
|
+
rb_m_wtime(VALUE self)
|
322
|
+
{
|
323
|
+
double time;
|
324
|
+
time = MPI_Wtime();
|
325
|
+
return rb_float_new(time);
|
326
|
+
}
|
327
|
+
|
328
|
+
static VALUE
|
329
|
+
rb_m_waitall(VALUE self, VALUE rary)
|
330
|
+
{
|
331
|
+
struct _Request *req;
|
332
|
+
MPI_Request *request;
|
333
|
+
MPI_Status *status;
|
334
|
+
VALUE rb_status;
|
335
|
+
long count, i;
|
336
|
+
|
337
|
+
count = RARRAY_LEN(rary);
|
338
|
+
|
339
|
+
request = ALLOCA_N(MPI_Request, count);
|
340
|
+
for (i=0; i<count; i++) {
|
341
|
+
Data_Get_Struct(rb_ary_entry(rary,i), struct _Request, req);
|
342
|
+
request[i] = req->Request;
|
343
|
+
}
|
344
|
+
rb_status = rb_ary_new2(count);
|
345
|
+
status = ALLOC_N(MPI_Status, count);
|
346
|
+
check_error(MPI_Waitall(count, request, status));
|
347
|
+
for (i=0; i<count; i++)
|
348
|
+
rb_ary_push(rb_status, Data_Wrap_Struct(cStatus, NULL, Status_free, &(status[i])));
|
349
|
+
return rb_status;
|
350
|
+
}
|
316
351
|
|
317
352
|
// MPI::Comm
|
318
353
|
/*
|
@@ -465,11 +500,124 @@ rb_comm_gather(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_root)
|
|
465
500
|
if (recvcount < sendcount*size)
|
466
501
|
rb_raise(rb_eArgError, "recvbuf is too small");
|
467
502
|
recvcount = sendcount;
|
503
|
+
} else {
|
504
|
+
recvtype = sendtype; // to avoid segmentation fault in an environment
|
468
505
|
}
|
469
506
|
check_error(MPI_Gather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm->Comm));
|
470
507
|
return Qnil;
|
471
508
|
}
|
472
509
|
static VALUE
|
510
|
+
rb_comm_igather(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_root)
|
511
|
+
{
|
512
|
+
void *sendbuf, *recvbuf = NULL;
|
513
|
+
int sendcount=0, recvcount = 0;
|
514
|
+
MPI_Datatype sendtype, recvtype = 0;
|
515
|
+
int root, rank, size;
|
516
|
+
struct _Comm *comm;
|
517
|
+
struct _Request *request;
|
518
|
+
VALUE rb_request;
|
519
|
+
OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
|
520
|
+
root = NUM2INT(rb_root);
|
521
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
522
|
+
check_error(MPI_Comm_rank(comm->Comm, &rank));
|
523
|
+
check_error(MPI_Comm_size(comm->Comm, &size));
|
524
|
+
if (rank == root) {
|
525
|
+
OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
|
526
|
+
if (recvcount < sendcount*size)
|
527
|
+
rb_raise(rb_eArgError, "recvbuf is too small");
|
528
|
+
recvcount = sendcount;
|
529
|
+
} else {
|
530
|
+
recvtype = sendtype; // to avoid segmentation fault in an environment
|
531
|
+
}
|
532
|
+
rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
|
533
|
+
request->free = true;
|
534
|
+
check_error(MPI_Igather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm->Comm, &(request->Request)));
|
535
|
+
return rb_request;
|
536
|
+
}
|
537
|
+
static VALUE
|
538
|
+
rb_comm_gatherv(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_recvcounts, VALUE rb_displs, VALUE rb_root)
|
539
|
+
{
|
540
|
+
void *sendbuf, *recvbuf = NULL;
|
541
|
+
int sendcount=0, bufsize=0;
|
542
|
+
int *recvcounts = NULL, *displs = NULL;
|
543
|
+
MPI_Datatype sendtype, recvtype = 0;
|
544
|
+
int root, rank, size;
|
545
|
+
struct _Comm *comm;
|
546
|
+
int max, tmp;
|
547
|
+
int i;
|
548
|
+
OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
|
549
|
+
root = NUM2INT(rb_root);
|
550
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
551
|
+
check_error(MPI_Comm_rank(comm->Comm, &rank));
|
552
|
+
check_error(MPI_Comm_size(comm->Comm, &size));
|
553
|
+
if (rank == root) {
|
554
|
+
if ( RARRAY_LEN(rb_recvcounts) != size )
|
555
|
+
rb_raise(rb_eArgError, "length of recvcounts must be the same as the group size");
|
556
|
+
if ( RARRAY_LEN(rb_displs) != size )
|
557
|
+
rb_raise(rb_eArgError, "length of displs must be the same as the group size");
|
558
|
+
recvcounts = ALLOCA_N(int, size);
|
559
|
+
displs = ALLOCA_N(int, size);
|
560
|
+
max = 0;
|
561
|
+
for (i=0; i<size; i++) {
|
562
|
+
recvcounts[i] = NUM2INT(rb_ary_entry(rb_recvcounts,i));
|
563
|
+
displs[i] = NUM2INT(rb_ary_entry(rb_displs,i));
|
564
|
+
tmp = displs[i] + recvcounts[i];
|
565
|
+
if (tmp > max) max = tmp;
|
566
|
+
}
|
567
|
+
OBJ2C(rb_recvbuf, bufsize, recvbuf, recvtype, 0);
|
568
|
+
if (bufsize < max)
|
569
|
+
rb_raise(rb_eArgError, "recvbuf is too small");
|
570
|
+
} else {
|
571
|
+
recvtype = sendtype; // to avoid segmentation fault in an environment
|
572
|
+
}
|
573
|
+
check_error(MPI_Gatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, root, comm->Comm));
|
574
|
+
return Qnil;
|
575
|
+
}
|
576
|
+
static VALUE
|
577
|
+
rb_comm_igatherv(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_recvcounts, VALUE rb_displs, VALUE rb_root)
|
578
|
+
{
|
579
|
+
void *sendbuf, *recvbuf = NULL;
|
580
|
+
int sendcount=0, bufsize=0;
|
581
|
+
int *recvcounts = NULL, *displs = NULL;
|
582
|
+
MPI_Datatype sendtype, recvtype = 0;
|
583
|
+
int root, rank, size;
|
584
|
+
struct _Comm *comm;
|
585
|
+
struct _Request *request;
|
586
|
+
VALUE rb_request;
|
587
|
+
int max, tmp;
|
588
|
+
int i;
|
589
|
+
|
590
|
+
OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
|
591
|
+
root = NUM2INT(rb_root);
|
592
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
593
|
+
check_error(MPI_Comm_rank(comm->Comm, &rank));
|
594
|
+
check_error(MPI_Comm_size(comm->Comm, &size));
|
595
|
+
if (rank == root) {
|
596
|
+
recvcounts = ALLOCA_N(int, size);
|
597
|
+
displs = ALLOCA_N(int, size);
|
598
|
+
max = 0;
|
599
|
+
if ( RARRAY_LEN(rb_recvcounts) != size )
|
600
|
+
rb_raise(rb_eArgError, "length of recvcounts must be the same as the group size");
|
601
|
+
if ( RARRAY_LEN(rb_displs) != size )
|
602
|
+
rb_raise(rb_eArgError, "length of displs must be the same as the group size");
|
603
|
+
for (i=0; i<size; i++) {
|
604
|
+
recvcounts[i] = NUM2INT(rb_ary_entry(rb_recvcounts,i));
|
605
|
+
displs[i] = NUM2INT(rb_ary_entry(rb_displs,i));
|
606
|
+
tmp = displs[i] + recvcounts[i];
|
607
|
+
if (tmp > max) max = tmp;
|
608
|
+
}
|
609
|
+
OBJ2C(rb_recvbuf, bufsize, recvbuf, recvtype, 0);
|
610
|
+
if (bufsize < max)
|
611
|
+
rb_raise(rb_eArgError, "recvbuf is too small");
|
612
|
+
} else {
|
613
|
+
recvtype = sendtype; // to avoid segmentation fault in an environment
|
614
|
+
}
|
615
|
+
rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
|
616
|
+
request->free = true;
|
617
|
+
check_error(MPI_Igatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, root, comm->Comm, &(request->Request)));
|
618
|
+
return rb_request;
|
619
|
+
}
|
620
|
+
static VALUE
|
473
621
|
rb_comm_allgather(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf)
|
474
622
|
{
|
475
623
|
void *sendbuf, *recvbuf;
|
@@ -489,6 +637,105 @@ rb_comm_allgather(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf)
|
|
489
637
|
return Qnil;
|
490
638
|
}
|
491
639
|
static VALUE
|
640
|
+
rb_comm_iallgather(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf)
|
641
|
+
{
|
642
|
+
void *sendbuf, *recvbuf;
|
643
|
+
int sendcount=0, recvcount=0;
|
644
|
+
MPI_Datatype sendtype, recvtype;
|
645
|
+
int rank, size;
|
646
|
+
struct _Comm *comm;
|
647
|
+
struct _Request *request;
|
648
|
+
VALUE rb_request;
|
649
|
+
OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
|
650
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
651
|
+
check_error(MPI_Comm_rank(comm->Comm, &rank));
|
652
|
+
check_error(MPI_Comm_size(comm->Comm, &size));
|
653
|
+
OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
|
654
|
+
if (recvcount < sendcount*size)
|
655
|
+
rb_raise(rb_eArgError, "recvbuf is too small");
|
656
|
+
recvcount = sendcount;
|
657
|
+
rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
|
658
|
+
request->free = true;
|
659
|
+
check_error(MPI_Iallgather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm->Comm, &(request->Request)));
|
660
|
+
return rb_request;
|
661
|
+
}
|
662
|
+
static VALUE
|
663
|
+
rb_comm_allgatherv(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_recvcounts, VALUE rb_displs)
|
664
|
+
{
|
665
|
+
void *sendbuf, *recvbuf;
|
666
|
+
int sendcount=0, bufsize=0;
|
667
|
+
int *recvcounts, *displs;
|
668
|
+
MPI_Datatype sendtype, recvtype;
|
669
|
+
int rank, size;
|
670
|
+
struct _Comm *comm;
|
671
|
+
int max, tmp;
|
672
|
+
int i;
|
673
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
674
|
+
check_error(MPI_Comm_rank(comm->Comm, &rank));
|
675
|
+
check_error(MPI_Comm_size(comm->Comm, &size));
|
676
|
+
if ( RARRAY_LEN(rb_recvcounts) != size )
|
677
|
+
rb_raise(rb_eArgError, "length of recvcounts must be the same as the group size");
|
678
|
+
if ( RARRAY_LEN(rb_displs) != size )
|
679
|
+
rb_raise(rb_eArgError, "length of displs must be the same as the group size");
|
680
|
+
recvcounts = ALLOCA_N(int, size);
|
681
|
+
displs = ALLOCA_N(int, size);
|
682
|
+
max = 0;
|
683
|
+
for (i=0; i<size; i++) {
|
684
|
+
recvcounts[i] = NUM2INT(rb_ary_entry(rb_recvcounts,i));
|
685
|
+
displs[i] = NUM2INT(rb_ary_entry(rb_displs,i));
|
686
|
+
tmp = displs[i] + recvcounts[i];
|
687
|
+
if (tmp > max) max = tmp;
|
688
|
+
}
|
689
|
+
OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
|
690
|
+
if (sendcount != recvcounts[rank])
|
691
|
+
rb_raise(rb_eArgError, "length of sendbuf is not the same as recvcounts[rank]");
|
692
|
+
OBJ2C(rb_recvbuf, bufsize, recvbuf, recvtype, 0);
|
693
|
+
if (bufsize < max)
|
694
|
+
rb_raise(rb_eArgError, "recvbuf is too small");
|
695
|
+
check_error(MPI_Allgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm->Comm));
|
696
|
+
return Qnil;
|
697
|
+
}
|
698
|
+
static VALUE
|
699
|
+
rb_comm_iallgatherv(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_recvcounts, VALUE rb_displs)
|
700
|
+
{
|
701
|
+
void *sendbuf, *recvbuf;
|
702
|
+
int sendcount=0, bufsize=0;
|
703
|
+
int *recvcounts, *displs;
|
704
|
+
MPI_Datatype sendtype, recvtype;
|
705
|
+
int rank, size;
|
706
|
+
struct _Comm *comm;
|
707
|
+
struct _Request *request;
|
708
|
+
VALUE rb_request;
|
709
|
+
int max, tmp;
|
710
|
+
int i;
|
711
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
712
|
+
check_error(MPI_Comm_rank(comm->Comm, &rank));
|
713
|
+
check_error(MPI_Comm_size(comm->Comm, &size));
|
714
|
+
if ( RARRAY_LEN(rb_recvcounts) != size )
|
715
|
+
rb_raise(rb_eArgError, "length of recvcounts must be the same as the group size");
|
716
|
+
if ( RARRAY_LEN(rb_displs) != size )
|
717
|
+
rb_raise(rb_eArgError, "length of displs must be the same as the group size");
|
718
|
+
recvcounts = ALLOCA_N(int, size);
|
719
|
+
displs = ALLOCA_N(int, size);
|
720
|
+
max = 0;
|
721
|
+
for (i=0; i<size; i++) {
|
722
|
+
recvcounts[i] = NUM2INT(rb_ary_entry(rb_recvcounts,i));
|
723
|
+
displs[i] = NUM2INT(rb_ary_entry(rb_displs,i));
|
724
|
+
tmp = displs[i] + recvcounts[i];
|
725
|
+
if (tmp > max) max = tmp;
|
726
|
+
}
|
727
|
+
OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
|
728
|
+
if (sendcount != recvcounts[rank])
|
729
|
+
rb_raise(rb_eArgError, "length of sendbuf is not the same as recvcounts[rank]");
|
730
|
+
OBJ2C(rb_recvbuf, bufsize, recvbuf, recvtype, 0);
|
731
|
+
if (bufsize < max)
|
732
|
+
rb_raise(rb_eArgError, "recvbuf is too small");
|
733
|
+
rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
|
734
|
+
request->free = true;
|
735
|
+
check_error(MPI_Iallgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm->Comm, &(request->Request)));
|
736
|
+
return rb_request;
|
737
|
+
}
|
738
|
+
static VALUE
|
492
739
|
rb_comm_bcast(VALUE self, VALUE rb_buffer, VALUE rb_root)
|
493
740
|
{
|
494
741
|
void *buffer;
|
@@ -503,6 +750,24 @@ rb_comm_bcast(VALUE self, VALUE rb_buffer, VALUE rb_root)
|
|
503
750
|
return Qnil;
|
504
751
|
}
|
505
752
|
static VALUE
|
753
|
+
rb_comm_ibcast(VALUE self, VALUE rb_buffer, VALUE rb_root)
|
754
|
+
{
|
755
|
+
void *buffer;
|
756
|
+
int count=0;
|
757
|
+
MPI_Datatype type;
|
758
|
+
int root;
|
759
|
+
struct _Comm *comm;
|
760
|
+
struct _Request *request;
|
761
|
+
VALUE rb_request;
|
762
|
+
OBJ2C(rb_buffer, count, buffer, type, 0);
|
763
|
+
root = NUM2INT(rb_root);
|
764
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
765
|
+
rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
|
766
|
+
request->free = true;
|
767
|
+
check_error(MPI_Ibcast(buffer, count, type, root, comm->Comm, &(request->Request)));
|
768
|
+
return rb_request;
|
769
|
+
}
|
770
|
+
static VALUE
|
506
771
|
rb_comm_scatter(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_root)
|
507
772
|
{
|
508
773
|
void *sendbuf = NULL, *recvbuf;
|
@@ -525,6 +790,110 @@ rb_comm_scatter(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_root)
|
|
525
790
|
return Qnil;
|
526
791
|
}
|
527
792
|
static VALUE
|
793
|
+
rb_comm_iscatter(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_root)
|
794
|
+
{
|
795
|
+
void *sendbuf = NULL, *recvbuf;
|
796
|
+
int sendcount = 0, recvcount=0;
|
797
|
+
MPI_Datatype sendtype = 0, recvtype;
|
798
|
+
int root, rank, size;
|
799
|
+
struct _Comm *comm;
|
800
|
+
struct _Request *request;
|
801
|
+
VALUE rb_request;
|
802
|
+
OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
|
803
|
+
root = NUM2INT(rb_root);
|
804
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
805
|
+
check_error(MPI_Comm_rank(comm->Comm, &rank));
|
806
|
+
check_error(MPI_Comm_size(comm->Comm, &size));
|
807
|
+
if (rank == root) {
|
808
|
+
OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
|
809
|
+
if (sendcount > recvcount*size)
|
810
|
+
rb_raise(rb_eArgError, "recvbuf is too small");
|
811
|
+
sendcount = recvcount;
|
812
|
+
}
|
813
|
+
rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
|
814
|
+
request->free = true;
|
815
|
+
check_error(MPI_Iscatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm->Comm, &(request->Request)));
|
816
|
+
return rb_request;
|
817
|
+
}
|
818
|
+
static VALUE
|
819
|
+
rb_comm_scatterv(VALUE self, VALUE rb_sendbuf, VALUE rb_sendcounts, VALUE rb_displs, VALUE rb_recvbuf, VALUE rb_root)
|
820
|
+
{
|
821
|
+
void *sendbuf = NULL, *recvbuf;
|
822
|
+
int recvcount = 0, bufsize=0;
|
823
|
+
int *sendcounts, *displs;
|
824
|
+
MPI_Datatype sendtype = 0, recvtype;
|
825
|
+
int root, rank, size;
|
826
|
+
struct _Comm *comm;
|
827
|
+
int max, tmp;
|
828
|
+
int i;
|
829
|
+
OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
|
830
|
+
root = NUM2INT(rb_root);
|
831
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
832
|
+
check_error(MPI_Comm_rank(comm->Comm, &rank));
|
833
|
+
check_error(MPI_Comm_size(comm->Comm, &size));
|
834
|
+
if (rank == root) {
|
835
|
+
if ( RARRAY_LEN(rb_sendcounts) != size )
|
836
|
+
rb_raise(rb_eArgError, "length of sendcounts must be the same as the group size");
|
837
|
+
if ( RARRAY_LEN(rb_displs) != size )
|
838
|
+
rb_raise(rb_eArgError, "length of displs must be the same as the group size");
|
839
|
+
sendcounts = ALLOCA_N(int, size);
|
840
|
+
displs = ALLOCA_N(int, size);
|
841
|
+
max = 0;
|
842
|
+
for (i=0; i<size; i++) {
|
843
|
+
sendcounts[i] = NUM2INT(rb_ary_entry(rb_sendcounts,i));
|
844
|
+
displs[i] = NUM2INT(rb_ary_entry(rb_displs,i));
|
845
|
+
tmp = displs[i] + sendcounts[i];
|
846
|
+
if (tmp > max) max = tmp;
|
847
|
+
}
|
848
|
+
OBJ2C(rb_sendbuf, bufsize, sendbuf, sendtype, 0);
|
849
|
+
if (bufsize < max)
|
850
|
+
rb_raise(rb_eArgError, "sendbuf is too small");
|
851
|
+
}
|
852
|
+
check_error(MPI_Scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm->Comm));
|
853
|
+
return Qnil;
|
854
|
+
}
|
855
|
+
static VALUE
|
856
|
+
rb_comm_iscatterv(VALUE self, VALUE rb_sendbuf, VALUE rb_sendcounts, VALUE rb_displs, VALUE rb_recvbuf, VALUE rb_root)
|
857
|
+
{
|
858
|
+
void *sendbuf = NULL, *recvbuf;
|
859
|
+
int recvcount = 0, bufsize=0;
|
860
|
+
int *sendcounts, *displs;
|
861
|
+
MPI_Datatype sendtype = 0, recvtype;
|
862
|
+
int root, rank, size;
|
863
|
+
struct _Comm *comm;
|
864
|
+
struct _Request *request;
|
865
|
+
VALUE rb_request;
|
866
|
+
int max, tmp;
|
867
|
+
int i;
|
868
|
+
OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
|
869
|
+
root = NUM2INT(rb_root);
|
870
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
871
|
+
check_error(MPI_Comm_rank(comm->Comm, &rank));
|
872
|
+
check_error(MPI_Comm_size(comm->Comm, &size));
|
873
|
+
if (rank == root) {
|
874
|
+
if ( RARRAY_LEN(rb_sendcounts) != size )
|
875
|
+
rb_raise(rb_eArgError, "length of sendcounts must be the same as the group size");
|
876
|
+
if ( RARRAY_LEN(rb_displs) != size )
|
877
|
+
rb_raise(rb_eArgError, "length of displs must be the same as the group size");
|
878
|
+
sendcounts = ALLOCA_N(int, size);
|
879
|
+
displs = ALLOCA_N(int, size);
|
880
|
+
max = 0;
|
881
|
+
for (i=0; i<size; i++) {
|
882
|
+
sendcounts[i] = NUM2INT(rb_ary_entry(rb_sendcounts,i));
|
883
|
+
displs[i] = NUM2INT(rb_ary_entry(rb_displs,i));
|
884
|
+
tmp = displs[i] + sendcounts[i];
|
885
|
+
if (tmp > max) max = tmp;
|
886
|
+
}
|
887
|
+
OBJ2C(rb_sendbuf, bufsize, sendbuf, sendtype, 0);
|
888
|
+
if (bufsize < max)
|
889
|
+
rb_raise(rb_eArgError, "sendbuf is too small");
|
890
|
+
}
|
891
|
+
rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
|
892
|
+
request->free = true;
|
893
|
+
check_error(MPI_Iscatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm->Comm, &(request->Request)));
|
894
|
+
return rb_request;
|
895
|
+
}
|
896
|
+
static VALUE
|
528
897
|
rb_comm_sendrecv(VALUE self, VALUE rb_sendbuf, VALUE rb_dest, VALUE rb_sendtag, VALUE rb_recvbuf, VALUE rb_source, VALUE rb_recvtag)
|
529
898
|
{
|
530
899
|
void *sendbuf, *recvbuf;
|
@@ -567,6 +936,129 @@ rb_comm_alltoall(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf)
|
|
567
936
|
return Qnil;
|
568
937
|
}
|
569
938
|
static VALUE
|
939
|
+
rb_comm_ialltoall(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf)
|
940
|
+
{
|
941
|
+
void *sendbuf, *recvbuf;
|
942
|
+
int sendcount=0, recvcount=0;
|
943
|
+
MPI_Datatype sendtype, recvtype;
|
944
|
+
int size;
|
945
|
+
struct _Comm *comm;
|
946
|
+
struct _Request *request;
|
947
|
+
VALUE rb_request;
|
948
|
+
OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
|
949
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
950
|
+
check_error(MPI_Comm_size(comm->Comm, &size));
|
951
|
+
OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
|
952
|
+
if (recvcount < sendcount)
|
953
|
+
rb_raise(rb_eArgError, "recvbuf is too small");
|
954
|
+
recvcount = recvcount/size;
|
955
|
+
sendcount = sendcount/size;
|
956
|
+
rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
|
957
|
+
request->free = true;
|
958
|
+
check_error(MPI_Ialltoall(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm->Comm, &(request->Request)));
|
959
|
+
return rb_request;
|
960
|
+
}
|
961
|
+
static VALUE
|
962
|
+
rb_comm_alltoallv(VALUE self, VALUE rb_sendbuf, VALUE rb_sendcounts, VALUE rb_sdispls, VALUE rb_recvbuf, VALUE rb_recvcounts, VALUE rb_rdispls)
|
963
|
+
{
|
964
|
+
void *sendbuf, *recvbuf;
|
965
|
+
int bufsize=0;
|
966
|
+
int *sendcounts, *sdispls;
|
967
|
+
int *recvcounts, *rdispls;
|
968
|
+
MPI_Datatype sendtype, recvtype;
|
969
|
+
int size;
|
970
|
+
struct _Comm *comm;
|
971
|
+
int smax, rmax, tmp;
|
972
|
+
int i;
|
973
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
974
|
+
check_error(MPI_Comm_size(comm->Comm, &size));
|
975
|
+
if ( RARRAY_LEN(rb_sendcounts) != size )
|
976
|
+
rb_raise(rb_eArgError, "length of sendcounts must be the same as the group size");
|
977
|
+
if ( RARRAY_LEN(rb_sdispls) != size )
|
978
|
+
rb_raise(rb_eArgError, "length of sdispls must be the same as the group size");
|
979
|
+
if ( RARRAY_LEN(rb_recvcounts) != size )
|
980
|
+
rb_raise(rb_eArgError, "length of recvcounts must be the same as the group size");
|
981
|
+
if ( RARRAY_LEN(rb_rdispls) != size )
|
982
|
+
rb_raise(rb_eArgError, "length of rdispls must be the same as the group size");
|
983
|
+
sendcounts = ALLOCA_N(int, size);
|
984
|
+
sdispls = ALLOCA_N(int, size);
|
985
|
+
recvcounts = ALLOCA_N(int, size);
|
986
|
+
rdispls = ALLOCA_N(int, size);
|
987
|
+
smax = 0;
|
988
|
+
rmax = 0;
|
989
|
+
for (i=0; i<size; i++) {
|
990
|
+
sendcounts[i] = NUM2INT(rb_ary_entry(rb_sendcounts,i));
|
991
|
+
sdispls[i] = NUM2INT(rb_ary_entry(rb_sdispls,i));
|
992
|
+
recvcounts[i] = NUM2INT(rb_ary_entry(rb_recvcounts,i));
|
993
|
+
rdispls[i] = NUM2INT(rb_ary_entry(rb_rdispls,i));
|
994
|
+
tmp = sdispls[i] + sendcounts[i];
|
995
|
+
if(tmp > smax) smax = tmp;
|
996
|
+
tmp = rdispls[i] + recvcounts[i];
|
997
|
+
if(tmp > rmax) rmax = tmp;
|
998
|
+
}
|
999
|
+
OBJ2C(rb_sendbuf, bufsize, sendbuf, sendtype, 0);
|
1000
|
+
if (bufsize < smax)
|
1001
|
+
rb_raise(rb_eArgError, "sendbuf is too small");
|
1002
|
+
bufsize = 0;
|
1003
|
+
OBJ2C(rb_recvbuf, bufsize, recvbuf, recvtype, 0);
|
1004
|
+
if (bufsize < rmax)
|
1005
|
+
rb_raise(rb_eArgError, "recvbuf is too small");
|
1006
|
+
check_error(MPI_Alltoallv(sendbuf, sendcounts, sdispls, sendtype, recvbuf, recvcounts, rdispls, recvtype, comm->Comm));
|
1007
|
+
return Qnil;
|
1008
|
+
}
|
1009
|
+
static VALUE
|
1010
|
+
rb_comm_ialltoallv(VALUE self, VALUE rb_sendbuf, VALUE rb_sendcounts, VALUE rb_sdispls, VALUE rb_recvbuf, VALUE rb_recvcounts, VALUE rb_rdispls)
|
1011
|
+
{
|
1012
|
+
void *sendbuf, *recvbuf;
|
1013
|
+
int bufsize=0;
|
1014
|
+
int *sendcounts, *sdispls;
|
1015
|
+
int *recvcounts, *rdispls;
|
1016
|
+
MPI_Datatype sendtype, recvtype;
|
1017
|
+
int size;
|
1018
|
+
struct _Comm *comm;
|
1019
|
+
struct _Request *request;
|
1020
|
+
VALUE rb_request;
|
1021
|
+
int smax, rmax, tmp;
|
1022
|
+
int i;
|
1023
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
1024
|
+
check_error(MPI_Comm_size(comm->Comm, &size));
|
1025
|
+
if ( RARRAY_LEN(rb_sendcounts) != size )
|
1026
|
+
rb_raise(rb_eArgError, "length of sendcounts must be the same as the group size");
|
1027
|
+
if ( RARRAY_LEN(rb_sdispls) != size )
|
1028
|
+
rb_raise(rb_eArgError, "length of sdispls must be the same as the group size");
|
1029
|
+
if ( RARRAY_LEN(rb_recvcounts) != size )
|
1030
|
+
rb_raise(rb_eArgError, "length of recvcounts must be the same as the group size");
|
1031
|
+
if ( RARRAY_LEN(rb_rdispls) != size )
|
1032
|
+
rb_raise(rb_eArgError, "length of rdispls must be the same as the group size");
|
1033
|
+
sendcounts = ALLOCA_N(int, size);
|
1034
|
+
sdispls = ALLOCA_N(int, size);
|
1035
|
+
recvcounts = ALLOCA_N(int, size);
|
1036
|
+
rdispls = ALLOCA_N(int, size);
|
1037
|
+
smax = 0;
|
1038
|
+
rmax = 0;
|
1039
|
+
for (i=0; i<size; i++) {
|
1040
|
+
sendcounts[i] = NUM2INT(rb_ary_entry(rb_sendcounts,i));
|
1041
|
+
sdispls[i] = NUM2INT(rb_ary_entry(rb_sdispls,i));
|
1042
|
+
recvcounts[i] = NUM2INT(rb_ary_entry(rb_recvcounts,i));
|
1043
|
+
rdispls[i] = NUM2INT(rb_ary_entry(rb_rdispls,i));
|
1044
|
+
tmp = sdispls[i] + sendcounts[i];
|
1045
|
+
if(tmp > smax) smax = tmp;
|
1046
|
+
tmp = rdispls[i] + recvcounts[i];
|
1047
|
+
if(tmp > rmax) rmax = tmp;
|
1048
|
+
}
|
1049
|
+
OBJ2C(rb_sendbuf, bufsize, sendbuf, sendtype, 0);
|
1050
|
+
if (bufsize < smax)
|
1051
|
+
rb_raise(rb_eArgError, "sendbuf is too small");
|
1052
|
+
bufsize = 0;
|
1053
|
+
OBJ2C(rb_recvbuf, bufsize, recvbuf, recvtype, 0);
|
1054
|
+
if (bufsize < rmax)
|
1055
|
+
rb_raise(rb_eArgError, "recvbuf is too small");
|
1056
|
+
rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
|
1057
|
+
request->free = true;
|
1058
|
+
check_error(MPI_Ialltoallv(sendbuf, sendcounts, sdispls, sendtype, recvbuf, recvcounts, rdispls, recvtype, comm->Comm, &(request->Request)));
|
1059
|
+
return rb_request;
|
1060
|
+
}
|
1061
|
+
static VALUE
|
570
1062
|
rb_comm_reduce(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op, VALUE rb_root)
|
571
1063
|
{
|
572
1064
|
void *sendbuf, *recvbuf = NULL;
|
@@ -583,15 +1075,248 @@ rb_comm_reduce(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op, VALU
|
|
583
1075
|
if (rank == root) {
|
584
1076
|
OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
|
585
1077
|
if (recvcount != sendcount)
|
586
|
-
rb_raise(rb_eArgError, "sendbuf and recvbuf
|
1078
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same length");
|
587
1079
|
if (recvtype != sendtype)
|
588
|
-
rb_raise(rb_eArgError, "sendbuf and recvbuf
|
1080
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
|
589
1081
|
}
|
590
1082
|
Data_Get_Struct(rb_op, struct _Op, op);
|
591
1083
|
check_error(MPI_Reduce(sendbuf, recvbuf, sendcount, sendtype, op->Op, root, comm->Comm));
|
592
1084
|
return Qnil;
|
593
1085
|
}
|
594
1086
|
static VALUE
|
1087
|
+
rb_comm_ireduce(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op, VALUE rb_root)
|
1088
|
+
{
|
1089
|
+
void *sendbuf, *recvbuf = NULL;
|
1090
|
+
int sendcount=0, recvcount = 0;
|
1091
|
+
MPI_Datatype sendtype, recvtype = 0;
|
1092
|
+
int root, rank, size;
|
1093
|
+
struct _Comm *comm;
|
1094
|
+
struct _Op *op;
|
1095
|
+
struct _Request *request;
|
1096
|
+
VALUE rb_request;
|
1097
|
+
OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
|
1098
|
+
root = NUM2INT(rb_root);
|
1099
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
1100
|
+
check_error(MPI_Comm_rank(comm->Comm, &rank));
|
1101
|
+
check_error(MPI_Comm_size(comm->Comm, &size));
|
1102
|
+
if (rank == root) {
|
1103
|
+
OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
|
1104
|
+
if (recvcount != sendcount)
|
1105
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same length");
|
1106
|
+
if (recvtype != sendtype)
|
1107
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
|
1108
|
+
}
|
1109
|
+
Data_Get_Struct(rb_op, struct _Op, op);
|
1110
|
+
rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
|
1111
|
+
request->free = true;
|
1112
|
+
check_error(MPI_Ireduce(sendbuf, recvbuf, sendcount, sendtype, op->Op, root, comm->Comm, &(request->Request)));
|
1113
|
+
return rb_request;
|
1114
|
+
}
|
1115
|
+
static VALUE
|
1116
|
+
rb_comm_reduce_scatter(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_recvcounts, VALUE rb_op)
|
1117
|
+
{
|
1118
|
+
void *sendbuf, *recvbuf = NULL;
|
1119
|
+
int sendcount=0, bufsize = 0;
|
1120
|
+
int *recvcounts;
|
1121
|
+
MPI_Datatype sendtype, recvtype = 0;
|
1122
|
+
int rank, size;
|
1123
|
+
struct _Comm *comm;
|
1124
|
+
struct _Op *op;
|
1125
|
+
int i;
|
1126
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
1127
|
+
check_error(MPI_Comm_rank(comm->Comm, &rank));
|
1128
|
+
check_error(MPI_Comm_size(comm->Comm, &size));
|
1129
|
+
if ( RARRAY_LEN(rb_recvcounts) != size )
|
1130
|
+
rb_raise(rb_eArgError, "length of recvcounts must be the same as the group size");
|
1131
|
+
recvcounts = ALLOCA_N(int, size);
|
1132
|
+
sendcount = 0;
|
1133
|
+
for (i=0; i<size; i++) {
|
1134
|
+
recvcounts[i] = NUM2INT(rb_ary_entry(rb_recvcounts,i));
|
1135
|
+
sendcount += recvcounts[i];
|
1136
|
+
}
|
1137
|
+
OBJ2C(rb_sendbuf, bufsize, sendbuf, sendtype, 0);
|
1138
|
+
if (bufsize != sendcount)
|
1139
|
+
rb_raise(rb_eArgError, "length of sendbuf and total of recvcounts must be the same");
|
1140
|
+
bufsize = 0;
|
1141
|
+
OBJ2C(rb_recvbuf, bufsize, recvbuf, recvtype, 0);
|
1142
|
+
if (bufsize != recvcounts[rank])
|
1143
|
+
rb_raise(rb_eArgError, "length of recvbuf and recvcounts[myrank] must by the same");
|
1144
|
+
if (recvtype != sendtype)
|
1145
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
|
1146
|
+
Data_Get_Struct(rb_op, struct _Op, op);
|
1147
|
+
check_error(MPI_Reduce_scatter(sendbuf, recvbuf, recvcounts, sendtype, op->Op, comm->Comm));
|
1148
|
+
return Qnil;
|
1149
|
+
}
|
1150
|
+
static VALUE
|
1151
|
+
rb_comm_ireduce_scatter(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_recvcounts, VALUE rb_op)
|
1152
|
+
{
|
1153
|
+
void *sendbuf, *recvbuf = NULL;
|
1154
|
+
int sendcount=0, bufsize = 0;
|
1155
|
+
int *recvcounts;
|
1156
|
+
MPI_Datatype sendtype, recvtype = 0;
|
1157
|
+
int rank, size;
|
1158
|
+
struct _Comm *comm;
|
1159
|
+
struct _Op *op;
|
1160
|
+
struct _Request *request;
|
1161
|
+
VALUE rb_request;
|
1162
|
+
int i;
|
1163
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
1164
|
+
check_error(MPI_Comm_rank(comm->Comm, &rank));
|
1165
|
+
check_error(MPI_Comm_size(comm->Comm, &size));
|
1166
|
+
if ( RARRAY_LEN(rb_recvcounts) != size )
|
1167
|
+
rb_raise(rb_eArgError, "length of recvcounts must be the same as the group size");
|
1168
|
+
recvcounts = ALLOCA_N(int, size);
|
1169
|
+
sendcount = 0;
|
1170
|
+
for (i=0; i<size; i++) {
|
1171
|
+
recvcounts[i] = NUM2INT(rb_ary_entry(rb_recvcounts,i));
|
1172
|
+
sendcount += recvcounts[i];
|
1173
|
+
}
|
1174
|
+
OBJ2C(rb_sendbuf, bufsize, sendbuf, sendtype, 0);
|
1175
|
+
if (bufsize != sendcount)
|
1176
|
+
rb_raise(rb_eArgError, "length of sendbuf and total of recvcounts must be the same");
|
1177
|
+
bufsize = 0;
|
1178
|
+
OBJ2C(rb_recvbuf, bufsize, recvbuf, recvtype, 0);
|
1179
|
+
if (bufsize != recvcounts[rank])
|
1180
|
+
rb_raise(rb_eArgError, "length of recvbuf and recvcounts[myrank] must by the same");
|
1181
|
+
if (recvtype != sendtype)
|
1182
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
|
1183
|
+
Data_Get_Struct(rb_op, struct _Op, op);
|
1184
|
+
rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
|
1185
|
+
request->free = true;
|
1186
|
+
check_error(MPI_Ireduce_scatter(sendbuf, recvbuf, recvcounts, sendtype, op->Op, comm->Comm, &(request->Request)));
|
1187
|
+
return rb_request;
|
1188
|
+
}
|
1189
|
+
static VALUE
|
1190
|
+
rb_comm_reduce_scatter_block(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
|
1191
|
+
{
|
1192
|
+
void *sendbuf, *recvbuf = NULL;
|
1193
|
+
int sendcount=0, recvcount = 0;
|
1194
|
+
MPI_Datatype sendtype, recvtype = 0;
|
1195
|
+
int size;
|
1196
|
+
struct _Comm *comm;
|
1197
|
+
struct _Op *op;
|
1198
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
1199
|
+
check_error(MPI_Comm_size(comm->Comm, &size));
|
1200
|
+
OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
|
1201
|
+
OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
|
1202
|
+
if (sendcount != recvcount*size)
|
1203
|
+
rb_raise(rb_eArgError, "length of sendbuf must be length of recvbuf times rank size");
|
1204
|
+
if (recvtype != sendtype)
|
1205
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
|
1206
|
+
Data_Get_Struct(rb_op, struct _Op, op);
|
1207
|
+
check_error(MPI_Reduce_scatter_block(sendbuf, recvbuf, recvcount, sendtype, op->Op, comm->Comm));
|
1208
|
+
return Qnil;
|
1209
|
+
}
|
1210
|
+
static VALUE
|
1211
|
+
rb_comm_ireduce_scatter_block(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
|
1212
|
+
{
|
1213
|
+
void *sendbuf, *recvbuf = NULL;
|
1214
|
+
int sendcount=0, recvcount = 0;
|
1215
|
+
MPI_Datatype sendtype, recvtype = 0;
|
1216
|
+
int size;
|
1217
|
+
struct _Comm *comm;
|
1218
|
+
struct _Op *op;
|
1219
|
+
struct _Request *request;
|
1220
|
+
VALUE rb_request;
|
1221
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
1222
|
+
check_error(MPI_Comm_size(comm->Comm, &size));
|
1223
|
+
OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
|
1224
|
+
OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
|
1225
|
+
if (sendcount != recvcount*size)
|
1226
|
+
rb_raise(rb_eArgError, "length of sendbuf must be length of recvbuf times rank size");
|
1227
|
+
if (recvtype != sendtype)
|
1228
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
|
1229
|
+
Data_Get_Struct(rb_op, struct _Op, op);
|
1230
|
+
rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
|
1231
|
+
request->free = true;
|
1232
|
+
check_error(MPI_Ireduce_scatter_block(sendbuf, recvbuf, recvcount, sendtype, op->Op, comm->Comm, &(request->Request)));
|
1233
|
+
return rb_request;
|
1234
|
+
}
|
1235
|
+
static VALUE
|
1236
|
+
rb_comm_scan(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
|
1237
|
+
{
|
1238
|
+
void *sendbuf, *recvbuf = NULL;
|
1239
|
+
int sendcount=0, recvcount = 0;
|
1240
|
+
MPI_Datatype sendtype, recvtype = 0;
|
1241
|
+
struct _Comm *comm;
|
1242
|
+
struct _Op *op;
|
1243
|
+
OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
|
1244
|
+
OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
|
1245
|
+
if (sendcount != recvcount)
|
1246
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same length");
|
1247
|
+
if (recvtype != sendtype)
|
1248
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
|
1249
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
1250
|
+
Data_Get_Struct(rb_op, struct _Op, op);
|
1251
|
+
check_error(MPI_Scan(sendbuf, recvbuf, recvcount, sendtype, op->Op, comm->Comm));
|
1252
|
+
return Qnil;
|
1253
|
+
}
|
1254
|
+
static VALUE
|
1255
|
+
rb_comm_iscan(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
|
1256
|
+
{
|
1257
|
+
void *sendbuf, *recvbuf = NULL;
|
1258
|
+
int sendcount=0, recvcount = 0;
|
1259
|
+
MPI_Datatype sendtype, recvtype = 0;
|
1260
|
+
struct _Comm *comm;
|
1261
|
+
struct _Op *op;
|
1262
|
+
struct _Request *request;
|
1263
|
+
VALUE rb_request;
|
1264
|
+
OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
|
1265
|
+
OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
|
1266
|
+
if (sendcount != recvcount)
|
1267
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same length");
|
1268
|
+
if (recvtype != sendtype)
|
1269
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
|
1270
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
1271
|
+
Data_Get_Struct(rb_op, struct _Op, op);
|
1272
|
+
rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
|
1273
|
+
request->free = true;
|
1274
|
+
check_error(MPI_Iscan(sendbuf, recvbuf, recvcount, sendtype, op->Op, comm->Comm, &(request->Request)));
|
1275
|
+
return rb_request;
|
1276
|
+
}
|
1277
|
+
static VALUE
|
1278
|
+
rb_comm_exscan(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
|
1279
|
+
{
|
1280
|
+
void *sendbuf, *recvbuf = NULL;
|
1281
|
+
int sendcount=0, recvcount = 0;
|
1282
|
+
MPI_Datatype sendtype, recvtype = 0;
|
1283
|
+
struct _Comm *comm;
|
1284
|
+
struct _Op *op;
|
1285
|
+
OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
|
1286
|
+
OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
|
1287
|
+
if (sendcount != recvcount)
|
1288
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same length");
|
1289
|
+
if (recvtype != sendtype)
|
1290
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
|
1291
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
1292
|
+
Data_Get_Struct(rb_op, struct _Op, op);
|
1293
|
+
check_error(MPI_Exscan(sendbuf, recvbuf, recvcount, sendtype, op->Op, comm->Comm));
|
1294
|
+
return Qnil;
|
1295
|
+
}
|
1296
|
+
static VALUE
|
1297
|
+
rb_comm_iexscan(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
|
1298
|
+
{
|
1299
|
+
void *sendbuf, *recvbuf = NULL;
|
1300
|
+
int sendcount=0, recvcount = 0;
|
1301
|
+
MPI_Datatype sendtype, recvtype = 0;
|
1302
|
+
struct _Comm *comm;
|
1303
|
+
struct _Op *op;
|
1304
|
+
struct _Request *request;
|
1305
|
+
VALUE rb_request;
|
1306
|
+
OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
|
1307
|
+
OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
|
1308
|
+
if (sendcount != recvcount)
|
1309
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same length");
|
1310
|
+
if (recvtype != sendtype)
|
1311
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
|
1312
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
1313
|
+
Data_Get_Struct(rb_op, struct _Op, op);
|
1314
|
+
rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
|
1315
|
+
request->free = true;
|
1316
|
+
check_error(MPI_Iexscan(sendbuf, recvbuf, recvcount, sendtype, op->Op, comm->Comm, &(request->Request)));
|
1317
|
+
return rb_request;
|
1318
|
+
}
|
1319
|
+
static VALUE
|
595
1320
|
rb_comm_allreduce(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
|
596
1321
|
{
|
597
1322
|
void *sendbuf, *recvbuf;
|
@@ -606,14 +1331,40 @@ rb_comm_allreduce(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
|
|
606
1331
|
check_error(MPI_Comm_size(comm->Comm, &size));
|
607
1332
|
OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
|
608
1333
|
if (recvcount != sendcount)
|
609
|
-
rb_raise(rb_eArgError, "sendbuf and recvbuf
|
1334
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same length");
|
610
1335
|
if (recvtype != sendtype)
|
611
|
-
rb_raise(rb_eArgError, "sendbuf and recvbuf
|
1336
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
|
612
1337
|
Data_Get_Struct(rb_op, struct _Op, op);
|
613
1338
|
check_error(MPI_Allreduce(sendbuf, recvbuf, recvcount, recvtype, op->Op, comm->Comm));
|
614
1339
|
return Qnil;
|
615
1340
|
}
|
616
1341
|
static VALUE
|
1342
|
+
rb_comm_iallreduce(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
|
1343
|
+
{
|
1344
|
+
void *sendbuf, *recvbuf;
|
1345
|
+
int sendcount=0, recvcount=0;
|
1346
|
+
MPI_Datatype sendtype, recvtype;
|
1347
|
+
int rank, size;
|
1348
|
+
struct _Comm *comm;
|
1349
|
+
struct _Op *op;
|
1350
|
+
struct _Request *request;
|
1351
|
+
VALUE rb_request;
|
1352
|
+
OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
|
1353
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
1354
|
+
check_error(MPI_Comm_rank(comm->Comm, &rank));
|
1355
|
+
check_error(MPI_Comm_size(comm->Comm, &size));
|
1356
|
+
OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
|
1357
|
+
if (recvcount != sendcount)
|
1358
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same length");
|
1359
|
+
if (recvtype != sendtype)
|
1360
|
+
rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
|
1361
|
+
Data_Get_Struct(rb_op, struct _Op, op);
|
1362
|
+
rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
|
1363
|
+
request->free = true;
|
1364
|
+
check_error(MPI_Iallreduce(sendbuf, recvbuf, recvcount, recvtype, op->Op, comm->Comm, &(request->Request)));
|
1365
|
+
return rb_request;
|
1366
|
+
}
|
1367
|
+
static VALUE
|
617
1368
|
rb_comm_get_Errhandler(VALUE self)
|
618
1369
|
{
|
619
1370
|
struct _Comm *comm;
|
@@ -643,7 +1394,19 @@ rb_comm_barrier(VALUE self)
|
|
643
1394
|
struct _Comm *comm;
|
644
1395
|
Data_Get_Struct(self, struct _Comm, comm);
|
645
1396
|
check_error(MPI_Barrier(comm->Comm));
|
646
|
-
return
|
1397
|
+
return Qnil;
|
1398
|
+
}
|
1399
|
+
static VALUE
|
1400
|
+
rb_comm_ibarrier(VALUE self)
|
1401
|
+
{
|
1402
|
+
struct _Comm *comm;
|
1403
|
+
struct _Request *request;
|
1404
|
+
VALUE rb_request;
|
1405
|
+
Data_Get_Struct(self, struct _Comm, comm);
|
1406
|
+
rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
|
1407
|
+
request->free = true;
|
1408
|
+
check_error(MPI_Ibarrier(comm->Comm, &(request->Request)));
|
1409
|
+
return rb_request;
|
647
1410
|
}
|
648
1411
|
|
649
1412
|
// MPI::Request
|
@@ -698,8 +1461,10 @@ void Init_mpi()
|
|
698
1461
|
// MPI
|
699
1462
|
mMPI = rb_define_module("MPI");
|
700
1463
|
rb_define_module_function(mMPI, "Init", rb_m_init, -1);
|
701
|
-
rb_define_module_function(mMPI, "Finalize", rb_m_finalize,
|
1464
|
+
rb_define_module_function(mMPI, "Finalize", rb_m_finalize, 0);
|
702
1465
|
rb_define_module_function(mMPI, "Abort", rb_m_abort, 2);
|
1466
|
+
rb_define_module_function(mMPI, "Wtime", rb_m_wtime, 0);
|
1467
|
+
rb_define_module_function(mMPI, "Waitall", rb_m_waitall, 1);
|
703
1468
|
rb_define_const(mMPI, "VERSION", INT2NUM(MPI_VERSION));
|
704
1469
|
rb_define_const(mMPI, "SUBVERSION", INT2NUM(MPI_SUBVERSION));
|
705
1470
|
rb_define_const(mMPI, "SUCCESS", INT2NUM(MPI_SUCCESS));
|
@@ -710,22 +1475,50 @@ void Init_mpi()
|
|
710
1475
|
// rb_define_alloc_func(cComm, rb_comm_alloc);
|
711
1476
|
rb_define_private_method(cComm, "initialize", rb_comm_initialize, 0);
|
712
1477
|
rb_define_method(cComm, "rank", rb_comm_rank, 0);
|
1478
|
+
rb_define_method(cComm, "Rank", rb_comm_rank, 0);
|
713
1479
|
rb_define_method(cComm, "size", rb_comm_size, 0);
|
1480
|
+
rb_define_method(cComm, "Size", rb_comm_size, 0);
|
714
1481
|
rb_define_method(cComm, "Send", rb_comm_send, 3);
|
715
1482
|
rb_define_method(cComm, "Isend", rb_comm_isend, 3);
|
716
1483
|
rb_define_method(cComm, "Recv", rb_comm_recv, -1);
|
717
1484
|
rb_define_method(cComm, "Irecv", rb_comm_irecv, -1);
|
718
1485
|
rb_define_method(cComm, "Gather", rb_comm_gather, 3);
|
1486
|
+
rb_define_method(cComm, "Igather", rb_comm_igather, 3);
|
1487
|
+
rb_define_method(cComm, "Gatherv", rb_comm_gatherv, 5);
|
1488
|
+
rb_define_method(cComm, "Igatherv", rb_comm_igatherv, 5);
|
719
1489
|
rb_define_method(cComm, "Allgather", rb_comm_allgather, 2);
|
1490
|
+
rb_define_method(cComm, "Iallgather", rb_comm_iallgather, 2);
|
1491
|
+
rb_define_method(cComm, "Allgatherv", rb_comm_allgatherv, 4);
|
1492
|
+
rb_define_method(cComm, "Iallgatherv", rb_comm_iallgatherv, 4);
|
720
1493
|
rb_define_method(cComm, "Bcast", rb_comm_bcast, 2);
|
1494
|
+
rb_define_method(cComm, "Ibcast", rb_comm_ibcast, 2);
|
721
1495
|
rb_define_method(cComm, "Scatter", rb_comm_scatter, 3);
|
1496
|
+
rb_define_method(cComm, "Iscatter", rb_comm_iscatter, 3);
|
1497
|
+
rb_define_method(cComm, "Scatterv", rb_comm_scatterv, 5);
|
1498
|
+
rb_define_method(cComm, "Iscatterv", rb_comm_iscatterv, 5);
|
722
1499
|
rb_define_method(cComm, "Sendrecv", rb_comm_sendrecv, 6);
|
723
1500
|
rb_define_method(cComm, "Alltoall", rb_comm_alltoall, 2);
|
1501
|
+
rb_define_method(cComm, "Ialltoall", rb_comm_ialltoall, 2);
|
1502
|
+
rb_define_method(cComm, "Alltoallv", rb_comm_alltoallv, 6);
|
1503
|
+
rb_define_method(cComm, "Ialltoallv", rb_comm_ialltoallv, 6);
|
1504
|
+
// rb_define_method(cComm, "Alltoallw", rb_comm_alltoallw, 2);
|
1505
|
+
// rb_define_method(cComm, "Ialltoallw", rb_comm_ialltoallw, 2);
|
724
1506
|
rb_define_method(cComm, "Reduce", rb_comm_reduce, 4);
|
1507
|
+
rb_define_method(cComm, "Ireduce", rb_comm_ireduce, 4);
|
1508
|
+
rb_define_method(cComm, "Reduce_scatter", rb_comm_reduce_scatter, 4);
|
1509
|
+
rb_define_method(cComm, "Ireduce_scatter", rb_comm_ireduce_scatter, 4);
|
1510
|
+
rb_define_method(cComm, "Reduce_scatter_block", rb_comm_reduce_scatter_block, 3);
|
1511
|
+
rb_define_method(cComm, "Ireduce_scatter_block", rb_comm_ireduce_scatter_block, 3);
|
1512
|
+
rb_define_method(cComm, "Scan", rb_comm_scan, 3);
|
1513
|
+
rb_define_method(cComm, "Iscan", rb_comm_iscan, 3);
|
1514
|
+
rb_define_method(cComm, "Exscan", rb_comm_exscan, 3);
|
1515
|
+
rb_define_method(cComm, "Iexscan", rb_comm_iexscan, 3);
|
725
1516
|
rb_define_method(cComm, "Allreduce", rb_comm_allreduce, 3);
|
1517
|
+
rb_define_method(cComm, "Iallreduce", rb_comm_iallreduce, 3);
|
1518
|
+
rb_define_method(cComm, "Barrier", rb_comm_barrier, 0);
|
1519
|
+
rb_define_method(cComm, "Ibarrier", rb_comm_ibarrier, 0);
|
726
1520
|
rb_define_method(cComm, "Errhandler", rb_comm_get_Errhandler, 0);
|
727
1521
|
rb_define_method(cComm, "Errhandler=", rb_comm_set_Errhandler, 1);
|
728
|
-
rb_define_method(cComm, "Barrier", rb_comm_barrier, 0);
|
729
1522
|
|
730
1523
|
// MPI::Request
|
731
1524
|
cRequest = rb_define_class_under(mMPI, "Request", rb_cObject);
|