File: testcore3.c

package info (click to toggle)
gasnet 2025.8.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 17,424 kB
  • sloc: ansic: 114,758; cpp: 5,158; sh: 4,847; makefile: 2,715; perl: 1,774
file content (142 lines) | stat: -rw-r--r-- 4,670 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*   $Source: bitbucket.org:berkeleylab/gasnet.git/tests/testcore3.c $
 * Description: GASNet Active Messages conformance test
 * Copyright (c) 2010, The Regents of the University of California
 * Terms of use are as specified in license.txt
 */

#include <gasnetex.h>
#include <test.h>

static gex_Client_t      myclient;
static gex_EP_t    myep;
static gex_TM_t myteam;
static gex_Segment_t     mysegment;

gex_Rank_t mynode = 0;
gex_Rank_t next = 0;
gex_Rank_t prev = 0;
void *myseg = NULL;
void *nextseg = NULL;
void *prevseg = NULL;

void *addr_tbl[] = {
    (void*)NULL, /* Will become myseg */
    (void*)NULL,
    (void*)(uintptr_t)1,
    (void*)(~(uintptr_t)0),
#if PLATFORM_ARCH_32
    (void*)(uintptr_t)0x12345678
#else
    (void*)(uintptr_t)0x123456789abcdefLL
#endif
};
#define NUM_ADDRS (sizeof(addr_tbl)/sizeof(addr_tbl[0]))


#define hidx_ping_medhandler     201
#define hidx_pong_medhandler     202

#define hidx_ping_longhandler    203
#define hidx_pong_longhandler    204

volatile int flag = 0;

void ping_medhandler(gex_Token_t token, void *buf, size_t nbytes, gex_AM_Arg_t addr_idx) {
  void *source_addr = addr_tbl[(int)addr_idx];
  gex_AM_ReplyMedium0(token, hidx_pong_medhandler, source_addr, 0, GEX_EVENT_NOW, 0);
}
void pong_medhandler(gex_Token_t token, void *buf, size_t nbytes) {
  flag++;
}

void ping_longhandler(gex_Token_t token, void *buf, size_t nbytes, gex_AM_Arg_t addr_idx) {
  void *source_addr = addr_tbl[(int)addr_idx];
  if (buf != (addr_idx ? source_addr : prevseg)) {
    ERR("Long Request handler received buf=%p when expecting %p", buf, source_addr);
  }
  gex_AM_ReplyLong1(token, hidx_pong_longhandler, source_addr, 0, source_addr, GEX_EVENT_NOW, 0, addr_idx);
}
void pong_longhandler(gex_Token_t token, void *buf, size_t nbytes, gex_AM_Arg_t addr_idx) {
  void *source_addr = addr_tbl[(int)addr_idx];
  if (buf != (addr_idx ? source_addr : nextseg)) {
    ERR("Long Reply handler received buf=%p when expecting %p", buf, source_addr);
  }
  flag++;
}

/* ------------------------------------------------------------------------------------ */

static void testAMSrcAddr(void);

int main(int argc, char **argv) {
  gex_AM_Entry_t htable[] = { 
    { hidx_ping_medhandler,  (gex_AM_Fn_t)ping_medhandler,  GEX_FLAG_AM_REQUEST|GEX_FLAG_AM_MEDIUM, 1 },
    { hidx_pong_medhandler,  (gex_AM_Fn_t)pong_medhandler,  GEX_FLAG_AM_REPLY|GEX_FLAG_AM_MEDIUM, 0 },
    { hidx_ping_longhandler, (gex_AM_Fn_t)ping_longhandler, GEX_FLAG_AM_REQUEST|GEX_FLAG_AM_LONG, 1 },
    { hidx_pong_longhandler, (gex_AM_Fn_t)pong_longhandler, GEX_FLAG_AM_REPLY|GEX_FLAG_AM_LONG, 1 }
  };

  GASNET_Safe(gex_Client_Init(&myclient, &myep, &myteam, "testcore3", &argc, &argv, 0));
  GASNET_Safe(gex_EP_RegisterHandlers(myep, htable, sizeof(htable)/sizeof(gex_AM_Entry_t)));

  test_init("testcore3", 0, "[no argument]");
  if (argc > 1) test_usage();

  TEST_PRINT_CONDUITINFO();

  mynode = gex_TM_QueryRank(myteam);
  gex_Rank_t nnodes = gex_TM_QuerySize(myteam);

  next = (mynode + 1) % nnodes;
  prev = (mynode + nnodes - 1) % nnodes;

  BARRIER();

  // Test once prior to binding segments to the endpoints
  // addr_tbl[0] == nextseg == prevseg trivially (all NULL)
  testAMSrcAddr();

  BARRIER();

  GASNET_Safe(gex_Segment_Attach(&mysegment, myteam, TEST_SEGSZ_REQUEST));

  // Test again with a bound segment and intialized addr_tbl[0], nextseg and prevseg
  // (though they are all still NULL for GASNET_SEGMENT_EVERTHING)
  addr_tbl[0] = myseg = TEST_MYSEG();
  nextseg = TEST_SEG(next);
  prevseg = TEST_SEG(prev);

  BARRIER();

  testAMSrcAddr();

  MSG("done.");

  gasnet_exit(test_errs ? 1 : 0);
  return 0;
}

/* ------------------------------------------------------------------------------------ */
void testAMSrcAddr(void) {
    GASNET_BEGIN_FUNCTION();

    flag = 0;

    // GASNet spec says we ignore source_addr when nbytes==0, for both Medium and Long.
    // So, this test attempts various invalid source_address values.
    // We pass the index, i, to allow the Reply to test all the values as well.
    for (int i = 0; i < NUM_ADDRS; ++i) {
      void *source_addr = addr_tbl[i];
      int goal = flag + 1;

      gex_AM_RequestMedium1(myteam, next, hidx_ping_medhandler, source_addr, 0, GEX_EVENT_NOW, 0, i);
      GASNET_BLOCKUNTIL(flag == goal); ++goal;

      // GASNet-EX requires initiator's "dest_addr" be passed to handler as "buf", even when nbytes==0
      // So, we test that behavior in both the request and reply handlers.
      gex_AM_RequestLong1(myteam, next, hidx_ping_longhandler, source_addr, 0, source_addr, GEX_EVENT_NOW, 0, i);
      GASNET_BLOCKUNTIL(flag == goal); ++goal;
    }

    BARRIER();
}