ruby-mpi 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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 has the same length");
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 has the same type");
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 has the same length");
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 has the same type");
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 self;
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, -1);
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);