Skip to content

Commit 8df4882

Browse files
authored
Merge pull request #21 from BerkeleyLab/complex-double
Finish collective subroutine support
2 parents e7f2acd + a94b4b2 commit 8df4882

10 files changed

Lines changed: 203 additions & 32 deletions

install.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,11 @@ GASNET_CC="`$PKG_CONFIG $pkg --variable=GASNET_CC`"
289289
GASNET_CFLAGS="`$PKG_CONFIG $pkg --variable=GASNET_CFLAGS`"
290290
GASNET_CPPFLAGS="`$PKG_CONFIG $pkg --variable=GASNET_CPPFLAGS`"
291291

292+
if [ "$GASNET_CC" != "$FPM_CC" ]; then
293+
echo "GASNET_CC=$GASNET_CC" and "FPM_CC=$FPM_CC don't match"
294+
exit 1;
295+
fi
296+
292297
echo "# DO NOT EDIT OR COMMIT -- Created by caffeine/install.sh" > build/fpm.toml
293298
cp manifest/fpm.toml.template build/fpm.toml
294299
GASNET_LIB_LOCATIONS=`echo $GASNET_LIBS | awk '{locs=""; for(i = 1; i <= NF; i++) if ($i ~ /^-L/) {locs=(locs " " $i);}; print locs; }'`

src/caffeine/caffeine.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ static gex_Rank_t rank, size;
1818
const int double_Complex_workaround = CFI_type_double_Complex;
1919
#else
2020
const int float_Complex_workaround = 2052;
21-
const int double_Complex_workaround = 4011;
21+
const int double_Complex_workaround =4100;
2222
#endif
2323

2424
void caf_c_caffeinate(int argc, char *argv[])
@@ -63,7 +63,6 @@ void caf_c_sync_all()
6363
gasnet_barrier_wait(0,GASNET_BARRIERFLAG_ANONYMOUS);
6464
}
6565

66-
// GASNETT_INLINE(caf_c_co_reduce)
6766
void caf_c_co_reduce(
6867
CFI_cdesc_t* a_desc, int result_image, int* stat, char* errmsg, int num_elements, gex_Coll_ReduceFn_t* user_op, void* client_data
6968
)
@@ -187,24 +186,22 @@ void caf_c_co_sum(CFI_cdesc_t* a_desc, int result_image, int* stat, char* errmsg
187186
{
188187
gex_DT_t a_type;
189188

189+
size_t c_sizeof_a = a_desc->elem_len;
190+
190191
switch (a_desc->type)
191192
{
192193
case CFI_type_int32_t: a_type = GEX_DT_I32; break;
193194
case CFI_type_int64_t: a_type = GEX_DT_I64; break;
194195
case CFI_type_float: a_type = GEX_DT_FLT; break;
195196
case CFI_type_double: a_type = GEX_DT_DBL; break;
196-
case float_Complex_workaround: a_type = GEX_DT_FLT; num_elements *= 2; break;
197-
case double_Complex_workaround: a_type = GEX_DT_DBL; num_elements *= 2; break;
197+
case float_Complex_workaround: a_type = GEX_DT_FLT; num_elements *= 2; c_sizeof_a /= 2; break;
198+
case double_Complex_workaround: a_type = GEX_DT_DBL; num_elements *= 2; c_sizeof_a /= 2; break;
198199
default:
199200
set_stat_errmsg_or_abort(stat, errmsg, UNRECOGNIZED_TYPE, "");
200201
}
201202

202203
char* a_address = (char*) a_desc->base_addr;
203204

204-
size_t c_sizeof_a = a_desc->elem_len;
205-
206-
if (a_type == float_Complex_workaround || a_type == double_Complex_workaround) c_sizeof_a /= 2;
207-
208205
gex_Event_t ev;
209206

210207
if (result_image) {

src/caffeine/collective_subroutines/co_broadcast_s.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
submodule(collective_subroutines_m) co_broadcast_s
2-
use iso_c_binding, only : c_int, c_size_t, c_ptr, c_loc, c_sizeof, c_int64_t, c_double
2+
use iso_c_binding, only : c_ptr
33
use utilities_m, only : get_c_ptr
44
use caffeine_h_m, only : caf_c_co_broadcast
55
implicit none

src/caffeine/collective_subroutines/co_reduce_s.f90

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
! Terms of use are as specified in LICENSE.txt
33
submodule(collective_subroutines_m) co_reduce_s
44
use iso_c_binding, only : &
5-
c_int64_t, c_ptr, c_size_t, c_loc, c_double, c_null_ptr, c_funloc, c_associated, c_f_pointer, c_int, c_f_procpointer
5+
c_ptr, c_size_t, c_loc, c_null_ptr, c_funloc, c_associated, c_f_pointer, c_int, c_f_procpointer
66
use assert_m, only : assert
77
use intrinsic_array_m, only : intrinsic_array_t
88
use utilities_m, only : get_c_ptr, get_c_ptr_character, optional_value
@@ -16,11 +16,15 @@
1616
module procedure caf_co_reduce
1717

1818
type(c_ptr) :: stat_ptr = c_null_ptr, errmsg_ptr = c_null_ptr
19+
1920
procedure(c_int32_t_operation), pointer :: int32_op => null()
21+
procedure(c_int64_t_operation), pointer :: int64_op => null()
2022
procedure(c_float_operation), pointer :: float_op => null()
23+
procedure(c_double_operation), pointer :: double_op => null()
2124
procedure(c_bool_operation), pointer :: bool_op => null()
2225
procedure(c_char_operation), pointer :: char_op => null()
2326
procedure(c_float_complex_operation), pointer :: float_complex_op => null()
27+
procedure(c_double_complex_operation), pointer :: double_complex_op => null()
2428

2529
call assert(c_associated(operation), "caf_co_reduce: c_associated(operation)")
2630

@@ -31,6 +35,14 @@
3135
call c_f_procpointer(operation, int32_op)
3236
call caf_c_co_reduce(a, optional_value(result_image), stat_ptr, errmsg_ptr, &
3337
int(product(shape(a)), c_size_t), c_funloc(Coll_ReduceSub_c_int32_t), c_null_ptr)
38+
else if (caf_c_same_cfi_type(a, 0_c_int64_t)) then
39+
call c_f_procpointer(operation, int64_op)
40+
call caf_c_co_reduce(a, optional_value(result_image), stat_ptr, errmsg_ptr, &
41+
int(product(shape(a)), c_size_t), c_funloc(Coll_ReduceSub_c_int64_t), c_null_ptr)
42+
else if (caf_c_same_cfi_type(a, 1._c_double)) then
43+
call c_f_procpointer(operation, double_op)
44+
call caf_c_co_reduce(a, optional_value(result_image), stat_ptr, errmsg_ptr, &
45+
int(product(shape(a)), c_size_t), c_funloc(Coll_ReduceSub_c_double), c_null_ptr)
3446
else if (caf_c_same_cfi_type(a, 1._c_float)) then
3547
call c_f_procpointer(operation, float_op)
3648
call caf_c_co_reduce(a, optional_value(result_image), stat_ptr, errmsg_ptr, &
@@ -51,6 +63,10 @@
5163
call c_f_procpointer(operation, float_complex_op)
5264
call caf_c_co_reduce(a, optional_value(result_image), stat_ptr, errmsg_ptr, &
5365
int(product(shape(a)), c_size_t), c_funloc(Coll_ReduceSub_c_float_complex), c_null_ptr)
66+
else if (caf_c_same_cfi_type(a, (0._c_double, 0._c_double))) then
67+
call c_f_procpointer(operation, double_complex_op)
68+
call caf_c_co_reduce(a, optional_value(result_image), stat_ptr, errmsg_ptr, &
69+
int(product(shape(a)), c_size_t), c_funloc(Coll_ReduceSub_c_double_complex), c_null_ptr)
5470
else
5571
error stop "caf_co_reduce: unsupported type"
5672
end if
@@ -75,6 +91,42 @@ subroutine Coll_ReduceSub_c_int32_t(arg1, arg2_and_out, count, cdata) bind(C)
7591
end do
7692
end subroutine
7793

94+
subroutine Coll_ReduceSub_c_int64_t(arg1, arg2_and_out, count, cdata) bind(C)
95+
type(c_ptr), value :: arg1 !! "Left" operands
96+
type(c_ptr), value :: arg2_and_out !! "Right" operands and result
97+
integer(c_size_t), value :: count !! Operand count
98+
type(c_ptr), value :: cdata !! Client data
99+
integer(c_int64_t), pointer :: lhs(:)=>null(), rhs_and_result(:)=>null()
100+
integer(c_size_t) i
101+
102+
call assert(all([c_associated(arg1), c_associated(arg2_and_out)]), "Coll_ReduceSub_c_int64_t: operands associated")
103+
104+
call c_f_pointer(arg1, lhs, [count])
105+
call c_f_pointer(arg2_and_out, rhs_and_result, [count])
106+
107+
do concurrent(i=1:count)
108+
rhs_and_result(i) = int64_op(lhs(i), rhs_and_result(i))
109+
end do
110+
end subroutine
111+
112+
subroutine Coll_ReduceSub_c_double(arg1, arg2_and_out, count, cdata) bind(C)
113+
type(c_ptr), value :: arg1 !! "Left" operands
114+
type(c_ptr), value :: arg2_and_out !! "Right" operands and result
115+
integer(c_size_t), value :: count !! Operand count
116+
type(c_ptr), value :: cdata !! Client data
117+
real(c_double), pointer :: lhs(:)=>null(), rhs_and_result(:)=>null()
118+
integer(c_size_t) i
119+
120+
call assert(all([c_associated(arg1), c_associated(arg2_and_out)]), "Coll_ReduceSub_c_double: operands associated")
121+
122+
call c_f_pointer(arg1, lhs, [count])
123+
call c_f_pointer(arg2_and_out, rhs_and_result, [count])
124+
125+
do concurrent(i=1:count)
126+
rhs_and_result(i) = double_op(lhs(i), rhs_and_result(i))
127+
end do
128+
end subroutine
129+
78130
subroutine Coll_ReduceSub_c_float(arg1, arg2_and_out, count, cdata) bind(C)
79131
type(c_ptr), value :: arg1 !! "Left" operands
80132
type(c_ptr), value :: arg2_and_out !! "Right" operands and result
@@ -93,6 +145,24 @@ subroutine Coll_ReduceSub_c_float(arg1, arg2_and_out, count, cdata) bind(C)
93145
end do
94146
end subroutine
95147

148+
subroutine Coll_ReduceSub_c_double_complex(arg1, arg2_and_out, count, cdata) bind(C)
149+
type(c_ptr), value :: arg1 !! "Left" operands
150+
type(c_ptr), value :: arg2_and_out !! "Right" operands and result
151+
integer(c_size_t), value :: count !! Operand count
152+
type(c_ptr), value :: cdata !! Client data
153+
complex(c_double), pointer :: lhs(:)=>null(), rhs_and_result(:)=>null()
154+
integer(c_size_t) i
155+
156+
call assert(all([c_associated(arg1), c_associated(arg2_and_out)]), "Coll_ReduceSub_c_dobule_complex: operands associated")
157+
158+
call c_f_pointer(arg1, lhs, [count])
159+
call c_f_pointer(arg2_and_out, rhs_and_result, [count])
160+
161+
do concurrent(i=1:count)
162+
rhs_and_result(i) = double_complex_op(lhs(i), rhs_and_result(i))
163+
end do
164+
end subroutine
165+
96166
subroutine Coll_ReduceSub_c_float_complex(arg1, arg2_and_out, count, cdata) bind(C)
97167
type(c_ptr), value :: arg1 !! "Left" operands
98168
type(c_ptr), value :: arg2_and_out !! "Right" operands and result

src/caffeine/collective_subroutines_m.f90

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
! Copyright (c), The Regents of the University of California
22
! Terms of use are as specified in LICENSE.txt
33
module collective_subroutines_m
4-
use iso_c_binding, only : c_int32_t, c_float, c_char, c_bool, c_funptr
4+
use iso_c_binding, only : c_int32_t, c_int64_t, c_float, c_char, c_bool, c_funptr, c_double
55
implicit none
66

77
private
@@ -10,11 +10,15 @@ module collective_subroutines_m
1010
public :: caf_co_min
1111
public :: caf_co_reduce
1212
public :: caf_co_broadcast
13+
1314
public :: c_int32_t_operation
15+
public :: c_int64_t_operation
1416
public :: c_float_operation
17+
public :: c_double_operation
1518
public :: c_bool_operation
1619
public :: c_char_operation
1720
public :: c_float_complex_operation
21+
public :: c_double_complex_operation
1822

1923
abstract interface
2024

@@ -25,13 +29,27 @@ pure function c_int32_t_operation(lhs, rhs) result(lhs_op_rhs)
2529
integer(c_int32_t) lhs_op_rhs
2630
end function
2731

32+
pure function c_int64_t_operation(lhs, rhs) result(lhs_op_rhs)
33+
import c_int64_t
34+
implicit none
35+
integer(c_int64_t), intent(in) :: lhs, rhs
36+
integer(c_int64_t) lhs_op_rhs
37+
end function
38+
2839
pure function c_float_operation(lhs, rhs) result(lhs_op_rhs)
2940
import c_float
3041
implicit none
3142
real(c_float), intent(in) :: lhs, rhs
3243
real(c_float) lhs_op_rhs
3344
end function
3445

46+
pure function c_double_operation(lhs, rhs) result(lhs_op_rhs)
47+
import c_double
48+
implicit none
49+
real(c_double), intent(in) :: lhs, rhs
50+
real(c_double) lhs_op_rhs
51+
end function
52+
3553
pure function c_bool_operation(lhs, rhs) result(lhs_op_rhs)
3654
import c_bool
3755
implicit none
@@ -53,6 +71,13 @@ pure function c_float_complex_operation(lhs, rhs) result(lhs_op_rhs)
5371
complex(c_float) lhs_op_rhs
5472
end function
5573

74+
pure function c_double_complex_operation(lhs, rhs) result(lhs_op_rhs)
75+
import c_double
76+
implicit none
77+
complex(c_double), intent(in) :: lhs, rhs
78+
complex(c_double) lhs_op_rhs
79+
end function
80+
5681
end interface
5782

5883
interface

test/caf_co_broadcast_test.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module caf_co_broadcast_test
22
use caffeine_m, only : caf_co_broadcast, caf_num_images, caf_this_image
3-
use vegetables, only : result_t, test_item_t, assert_equals, describe, it, assert_equals, assert_that
3+
use vegetables, only : result_t, test_item_t, describe, it, assert_equals, assert_that
44

55
implicit none
66
private

test/caf_co_max_test.f90

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function test_caf_co_max() result(tests)
2121
,it("double precision 2D array elements with no optional arguments present", max_double_precision_2D_array) &
2222
,it("reverse-alphabetizes length-5 default character scalars with no optional arguments", &
2323
reverse_alphabetize_default_character_scalars) &
24-
,it("elements across images with 2D arrays of strings", max_elements_in_2D_string_arrays) &
24+
,it("elements across images with 3D arrays of strings", max_elements_in_3D_string_arrays) &
2525
])
2626
end function
2727

@@ -91,15 +91,15 @@ function max_double_precision_2D_array() result(result_)
9191
result_ = assert_that(all(array==tent))
9292
end function
9393

94-
function max_elements_in_2D_string_arrays() result(result_)
94+
function max_elements_in_3D_string_arrays() result(result_)
9595
type(result_t) result_
9696
character(len=*), parameter :: script(*) = ["To be ","or not","to ","be. "]
97-
character(len=len(script)), dimension(2,2) :: scramlet, co_max_scramlet
97+
character(len=len(script)), dimension(2,1,2) :: scramlet, co_max_scramlet
9898
integer i, cyclic_permutation(size(script))
9999

100100
associate(me => this_image())
101101
associate(cyclic_permutation => [(1 + mod(i-1,size(script)), i=me, me+size(script) )])
102-
scramlet = reshape(script(cyclic_permutation), [2,2])
102+
scramlet = reshape(script(cyclic_permutation), shape(scramlet))
103103
end associate
104104
end associate
105105

@@ -118,7 +118,7 @@ function max_elements_in_2D_string_arrays() result(result_)
118118
end associate
119119
end do
120120
end do
121-
expected_scramlet = reshape(expected_script, shape(scramlet))
121+
expected_scramlet = reshape(expected_script, shape(expected_scramlet))
122122

123123
result_ = assert_that(all(scramlet == co_max_scramlet),"all(scramlet == co_max_scramlet)")
124124
end block

test/caf_co_min_test.f90

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,14 @@ function min_double_precision_2D_array() result(result_)
9393

9494
function min_elements_in_2D_string_arrays() result(result_)
9595
type(result_t) result_
96-
character(len=*), parameter :: script(*) = ["To be ","or not","to ","be. "]
97-
character(len=len(script)), dimension(2,2) :: scramlet, co_min_scramlet
96+
character(len=*), parameter :: script(*) = &
97+
[character(len=len("the question.")) :: "To be ","or not"," to ","be."," That is ","the question."]
98+
character(len=len(script)), dimension(3,2) :: scramlet, co_min_scramlet
9899
integer i, cyclic_permutation(size(script))
99100

100101
associate(me => this_image())
101102
associate(cyclic_permutation => [(1 + mod(i-1,size(script)), i=me, me+size(script) )])
102-
scramlet = reshape(script(cyclic_permutation), [2,2])
103+
scramlet = reshape(script(cyclic_permutation), shape(scramlet))
103104
end associate
104105
end associate
105106

@@ -127,7 +128,7 @@ function min_elements_in_2D_string_arrays() result(result_)
127128

128129
function alphabetically_1st_scalar_string() result(result_)
129130
type(result_t) result_
130-
character(len=*), parameter :: words(*) = [character(len=len("loddy")):: "loddy","doddy","we","like","to","party"]
131+
character(len=*), parameter :: words(*) = [character(len=len("to party!")):: "Loddy","doddy","we","like","to party!"]
131132
character(len=:), allocatable :: my_word
132133

133134
associate(me => caf_this_image())

0 commit comments

Comments
 (0)