summaryrefslogtreecommitdiffstats
path: root/examples/h5ff_client_map.c
blob: 3c1e1982b324234308c75d2f85ddf122a8dace9a (plain)
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/* 

 * test_client_acg.c: Client side of Map Object

 */

#include <stdio.h>

#include <stdlib.h>

#include <assert.h>

#include <string.h>

#include "mpi.h"

#include "hdf5.h"


int main(int argc, char **argv) {
    const char file_name[]="map_file.h5";
    hid_t file_id;
    hid_t gid1, gid2;
    hid_t map1, map2, map3;
    hid_t fapl_id, dxpl_id;
    int my_rank, my_size;
    int provided;
    hid_t event_q;
    H5_status_t *status = NULL;
    int num_requests = 0, i;
    herr_t ret;
    hsize_t count = -1;
    int key, value;
    hbool_t exists = -1;
    H5_request_t req1;
    H5_status_t status1;

    MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
    if(MPI_THREAD_MULTIPLE != provided) {
        fprintf(stderr, "MPI does not have MPI_THREAD_MULTIPLE support\n");
        exit(1);
    }

    /* Call EFF_init to initialize the EFF stack.  

       As a result of this call, the Function Shipper client is started, 

       and HDF5 VOL calls are registered with the function shipper.

       An "IOD init" call is forwarded from the FS client to the FS server 

       which should already be running. */
    EFF_init(MPI_COMM_WORLD, MPI_INFO_NULL);

    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &my_size);
    fprintf(stderr, "APP processes = %d, my rank is %d\n", my_size, my_rank);

    fprintf(stderr, "Create the FAPL to set the IOD VOL plugin and create the file\n");
    /* Choose the IOD VOL plugin to use with this file. 

       First we create a file access property list. Then we call a new routine to set

       the IOD plugin to use with this fapl */
    fapl_id = H5Pcreate (H5P_FILE_ACCESS);
    H5Pset_fapl_iod(fapl_id, MPI_COMM_WORLD, MPI_INFO_NULL);

    /* create an event Queue for managing asynchronous requests.



       Event Queues will releive the use from managing and completing

       individual requests for every operation. Instead of passing a

       request for every operation, the event queue is passed and

       internally the HDF5 library creates a request and adds it to

       the event queue.



       Multiple Event queue can be created used by the application. */
    event_q = H5EQcreate(fapl_id);
    assert(event_q);

    /* create the file. This is asynchronous, but the file_id can be used. */
    file_id = H5Fcreate(file_name, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
    assert(file_id);

    /* create two groups */
    gid1 = H5Gcreate_ff(file_id, "G1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, 0, event_q);
    gid2 = H5Gcreate_ff(file_id, "G1/G2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, 0, event_q);

    /* Create Map objects with the key type and val type being 32 bit

       LE integers */
    map1 = H5Mcreate_ff(file_id, "MAP_1", H5T_STD_I32LE, H5T_STD_I32LE, 
                        H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT, 0, event_q);
    map2 = H5Mcreate_ff(file_id, "G1/MAP_2", H5T_STD_I32LE, H5T_STD_I32LE, 
                        H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT, 0, event_q);
    map3 = H5Mcreate_ff(file_id, "G1/G2/MAP_3", H5T_STD_I32LE, H5T_STD_I32LE, 
                        H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT, 0, event_q);

    {
        key = 1;
        value = 1000;
        ret = H5Mset_ff(map3, H5T_STD_I32LE, &key, H5T_STD_I32LE, &value,
                        H5P_DEFAULT, 0, event_q);
        assert(ret == 0);

        key = 2;
        value = 2000;
        ret = H5Mset_ff(map3, H5T_STD_I32LE, &key, H5T_STD_I32LE, &value,
                        H5P_DEFAULT, 0, event_q);
        assert(ret == 0);

        key = 3;
        value = 3000;
        ret = H5Mset_ff(map3, H5T_STD_I32LE, &key, H5T_STD_I32LE, &value,
                        H5P_DEFAULT, 0, event_q);
        assert(ret == 0);
    }

    ret = H5Mget_count_ff(map3, &count, 0, event_q);
    assert(ret == 0);

    key = 1;
    ret = H5Mexists_ff(map3, H5T_STD_I32LE, &key, &exists, 0, event_q);
    assert(ret == 0);

    key = 1;
    ret = H5Mdelete_ff(map3, H5T_STD_I32LE, &key, 0, event_q);
    assert(ret == 0);

    assert(H5Gclose_ff(gid1, event_q) == 0);
    assert(H5Gclose_ff(gid2, event_q) == 0);
    assert(H5Mclose_ff(map1, event_q) == 0);
    assert(H5Mclose_ff(map2, event_q) == 0);
    assert(H5Mclose_ff(map3, event_q) == 0);

    map3 = H5Mopen_ff(file_id, "G1/G2/MAP_3", H5P_DEFAULT, 0, event_q);

    {
        int key, value;

        key = 1;
        value = -1;
        ret = H5Mget_ff(map3, H5T_STD_I32LE, &key, H5T_STD_I32LE, &value,
                        H5P_DEFAULT, 0, event_q);

        if(H5EQpop(event_q, &req1) < 0)
            exit(1);
        assert(H5AOwait(req1, &status1) == 0);
        assert (status1);
        printf("Value recieved == %d\n", value);
        /* this is the fake value we sent from the server */
        assert(value == 1024);

        key = 1;
        value = -1;
        ret = H5Mget_ff(map3, H5T_STD_I32LE, &key, H5T_STD_I32LE, &value,
                        H5P_DEFAULT, 0, event_q);

        if(H5EQpop(event_q, &req1) < 0)
            exit(1);
        assert(H5AOwait(req1, &status1) == 0);
        assert (status1);

        /* this is the fake value we sent from the server */
        assert(value == 1024);
    }

    assert(H5Mclose_ff(map3, event_q) == 0);

    /* closing the container also acts as a wait all on all pending requests 

       on the container. */
    assert(H5Fclose_ff(file_id, event_q) == 0);

    fprintf(stderr, "\n*****************************************************************************************************************\n");
    fprintf(stderr, "Wait on everything in EQ and check Results of operations in EQ\n");
    fprintf(stderr, "*****************************************************************************************************************\n");

    /* wait on all requests and print completion status */
    H5EQwait(event_q, &num_requests, &status);
    fprintf(stderr, "%d requests in event queue. Completions: ", num_requests);
    for(i=0 ; i<num_requests; i++)
        fprintf(stderr, "%d ",status[i]);
    fprintf(stderr, "\n");
    free(status);

    assert (count == 3);
    assert (exists > 0);

    fprintf(stderr, "\n*****************************************************************************************************************\n");
    fprintf(stderr, "Finalize EFF stack\n");
    fprintf(stderr, "*****************************************************************************************************************\n");

    H5EQclose(event_q);
    H5Pclose(fapl_id);

    /* This finalizes the EFF stack. ships a terminate and IOD finalize to the server 

       and shutsdown the FS server (when all clients send the terminate request) 

       and client */
    EFF_finalize();

    MPI_Finalize();
    return 0;
}