-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add teams spec tests to "spec-example" directory #918
Changes from all commits
97ae44c
d454ea0
674785c
44a0694
077ee58
815bea8
e723937
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* This test program is derived from an example program in the | ||
* OpenSHMEM specification. | ||
*/ | ||
|
||
#include <shmemx.h> | ||
#include <shmem.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
#define NELEMS 32 | ||
|
||
int main(void) { | ||
shmem_init(); | ||
int mype = shmem_my_pe(); | ||
int npes = shmem_n_pes(); | ||
|
||
int *values = shmem_malloc(NELEMS * sizeof(int)); | ||
|
||
unsigned char *value_is_maximal = shmem_malloc(NELEMS * sizeof(unsigned char)); | ||
unsigned char *value_is_maximal_all = shmem_malloc(NELEMS * sizeof(unsigned char)); | ||
|
||
static int maximal_values_count = 0; | ||
static int maximal_values_total; | ||
|
||
srand((unsigned)mype); | ||
|
||
for (int i = 0; i < NELEMS; i++) { | ||
values[i] = rand() % npes; | ||
|
||
/* Track and count instances of maximal values (i.e., values equal to (npes-1)) */ | ||
value_is_maximal[i] = (values[i] == (npes - 1)) ? 1 : 0; | ||
maximal_values_count += value_is_maximal[i]; | ||
} | ||
|
||
/* Wait for all PEs to initialize reductions arrays */ | ||
shmemx_sync(SHMEMX_TEAM_WORLD); | ||
|
||
shmemx_or_reduce(SHMEMX_TEAM_WORLD, value_is_maximal_all, value_is_maximal, NELEMS); | ||
shmemx_sum_reduce(SHMEMX_TEAM_WORLD, &maximal_values_total, &maximal_values_count, 1); | ||
|
||
if (mype == 0) { | ||
printf("Found %d maximal random numbers across all PEs.\n", maximal_values_total); | ||
printf("A maximal number occured (at least once) at the following indices:\n"); | ||
for (int i = 0; i < NELEMS; i++) { | ||
if (value_is_maximal_all[i] == 1) { | ||
printf("%d ", i); | ||
} | ||
} | ||
printf("\n"); | ||
} | ||
|
||
shmem_finalize(); | ||
return 0; | ||
} | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* | ||
* This test program is derived from an example program in the | ||
* OpenSHMEM specification. | ||
*/ | ||
|
||
#include <shmemx.h> | ||
#include <shmem.h> | ||
#include <stdio.h> | ||
|
||
|
||
int main(void) | ||
{ | ||
static int sum = 0, val_2, val_3; | ||
shmemx_team_t team_2, team_3; | ||
shmem_ctx_t ctx_2, ctx_3; | ||
shmemx_team_config_t conf; | ||
|
||
shmem_init(); | ||
|
||
int npes = shmem_n_pes(); | ||
int mype = shmem_my_pe(); | ||
conf.num_contexts = 1; | ||
long cmask = SHMEMX_TEAM_NUM_CONTEXTS; | ||
|
||
/* Create team_2 with PEs numbered 0, 2, 4, ... */ | ||
int ret = shmemx_team_split_strided(SHMEMX_TEAM_WORLD, 0, 2, (npes + 1) / 2, &conf, cmask, &team_2); | ||
|
||
if (ret != 0) { | ||
printf("%d: Error creating team team_2 (%d)\n", mype, ret); | ||
shmem_global_exit(ret); | ||
} | ||
|
||
/* Create team_3 with PEs numbered 0, 3, 6, ... */ | ||
ret = shmemx_team_split_strided(SHMEMX_TEAM_WORLD, 0, 3, (npes + 2) / 3, &conf, cmask, &team_3); | ||
|
||
if (ret != 0) { | ||
printf("%d: Error creating team team_3 (%d)\n", mype, ret); | ||
shmem_global_exit(ret); | ||
} | ||
|
||
/* Create a context on team_2. */ | ||
ret = shmemx_team_create_ctx(team_2, 0, &ctx_2); | ||
|
||
if (ret != 0 && team_2 != SHMEMX_TEAM_INVALID) { | ||
printf("%d: Error creating context ctx_2 (%d)\n", mype, ret); | ||
shmem_global_exit(ret); | ||
} | ||
|
||
/* Create a context on team_3. */ | ||
ret = shmemx_team_create_ctx(team_3, 0, &ctx_3); | ||
|
||
if (ret != 0 && team_3 != SHMEMX_TEAM_INVALID) { | ||
printf("%d: Error creating context ctx_3 (%d)\n", mype, ret); | ||
shmem_global_exit(ret); | ||
} | ||
|
||
/* Within each team, put my PE number to my neighbor in a ring-based manner. */ | ||
if (ctx_2 != SHMEMX_CTX_INVALID) { | ||
int pe = shmemx_team_my_pe(team_2); | ||
shmem_ctx_int_put(ctx_2, &val_2, &pe, 1, (pe + 1) % shmemx_team_n_pes(team_2)); | ||
} | ||
|
||
if (ctx_3 != SHMEMX_CTX_INVALID) { | ||
int pe = shmemx_team_my_pe(team_3); | ||
shmem_ctx_int_put(ctx_3, &val_3, &pe, 1, (pe + 1) % shmemx_team_n_pes(team_3)); | ||
} | ||
|
||
/* Quiet both contexts and synchronize all PEs to complete the data transfers. */ | ||
shmem_ctx_quiet(ctx_2); | ||
shmem_ctx_quiet(ctx_3); | ||
shmemx_team_sync(SHMEMX_TEAM_WORLD); | ||
|
||
/* Sum the values among PEs that are in both team_2 and team_3 on PE 0 with ctx_2. */ | ||
if (team_3 != SHMEMX_TEAM_INVALID && team_2 != SHMEMX_TEAM_INVALID) | ||
shmem_ctx_int_atomic_add(ctx_2, &sum, val_2 + val_3, 0); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is an unreliable way to check, since context creation failure is local (not global)... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Whoops - right. So I just need to include a check for |
||
|
||
/* Quiet the context and synchronize PEs to complete the operation. */ | ||
shmem_ctx_quiet(ctx_2); | ||
shmemx_team_sync(SHMEMX_TEAM_WORLD); | ||
|
||
/* Validate the result. */ | ||
if (mype == 0) { | ||
int vsum = 0; | ||
for (int i = 0; i < npes; i ++) { | ||
if (i % 2 == 0 && i % 3 == 0) { | ||
vsum += ((i - 2) < 0) ? shmemx_team_n_pes(team_2) - 1 : | ||
shmemx_team_translate_pe(SHMEMX_TEAM_WORLD, i - 2, team_2); | ||
vsum += ((i - 3) < 0) ? shmemx_team_n_pes(team_3) - 1 : | ||
shmemx_team_translate_pe(SHMEMX_TEAM_WORLD, i - 3, team_3); | ||
} | ||
} | ||
if (sum != vsum) { | ||
fprintf(stderr, "Unexpected result, npes = %d, vsum = %d, sum = %d\n", shmem_n_pes(), vsum, sum); | ||
shmem_global_exit(1); | ||
} | ||
} | ||
|
||
/* Destroy contexts before teams. */ | ||
shmem_ctx_destroy(ctx_2); | ||
shmemx_team_destroy(team_2); | ||
|
||
shmem_ctx_destroy(ctx_3); | ||
shmemx_team_destroy(team_3); | ||
|
||
shmem_finalize(); | ||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* | ||
* This test program is derived from an example program in the | ||
* OpenSHMEM specification. | ||
*/ | ||
|
||
#include <shmemx.h> | ||
#include <shmem.h> | ||
#include <stdio.h> | ||
#include <math.h> | ||
|
||
/* Find x and y such that x * y == npes and abs(x - y) is minimized. */ | ||
static void find_xy_dims(int npes, int *x, int *y) { | ||
for(int divider = ceil(sqrt(npes)); divider >= 1; divider--) | ||
if (npes % divider == 0) { | ||
*x = divider; | ||
*y = npes / divider; | ||
return; | ||
} | ||
} | ||
|
||
/* Find x, y, and z such that x * y * z == npes and | ||
* abs(x - y) + abs(x - z) + abs(y - z) is minimized. */ | ||
static void find_xyz_dims(int npes, int *x, int *y, int *z) { | ||
for(int divider = ceil(cbrt(npes)); divider >= 1; divider--) | ||
if (npes % divider == 0) { | ||
*x = divider; | ||
find_xy_dims(npes / divider, y, z); | ||
return; | ||
} | ||
} | ||
|
||
int main(void) { | ||
int xdim, ydim, zdim; | ||
|
||
shmem_init(); | ||
int mype = shmem_my_pe(); | ||
int npes = shmem_n_pes(); | ||
|
||
find_xyz_dims(npes, &xdim, &ydim, &zdim); | ||
|
||
if (shmem_my_pe() == 0) printf("xdim = %d, ydim = %d, zdim = %d\n", xdim, ydim, zdim); | ||
|
||
shmemx_team_t xteam, yzteam, yteam, zteam; | ||
|
||
shmemx_team_split_2d(SHMEMX_TEAM_WORLD, xdim, NULL, 0, &xteam, NULL, 0, &yzteam); | ||
// yzteam is immediately ready to be used in collectives | ||
shmemx_team_split_2d(yzteam, ydim, NULL, 0, &yteam, NULL, 0, &zteam); | ||
|
||
// We don't need the yzteam anymore | ||
shmemx_team_destroy(yzteam); | ||
|
||
int my_x = shmemx_team_my_pe(xteam); | ||
int my_y = shmemx_team_my_pe(yteam); | ||
int my_z = shmemx_team_my_pe(zteam); | ||
|
||
for (int zdx = 0; zdx < zdim; zdx++) { | ||
for (int ydx = 0; ydx < ydim; ydx++) { | ||
for (int xdx = 0; xdx < xdim; xdx++) { | ||
if ((my_x == xdx) && (my_y == ydx) && (my_z == zdx)) { | ||
printf("(%d, %d, %d) is mype = %d\n", my_x, my_y, my_z, mype); | ||
} | ||
shmemx_team_sync(SHMEMX_TEAM_WORLD); | ||
} | ||
} | ||
} | ||
|
||
shmem_finalize(); | ||
return 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This example makes no sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the upside, it looks like it will work now, which is great.