Yet Another eXchange Tool 0.11.1
Loading...
Searching...
No Matches
test_idxvec.c
/*
* Keywords:
* Maintainer: Jörg Behrens <behrens@dkrz.de>
* Moritz Hanke <hanke@dkrz.de>
* Thomas Jahns <jahns@dkrz.de>
* URL: https://dkrz-sw.gitlab-pages.dkrz.de/yaxt/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of the DKRZ GmbH nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <mpi.h>
#include <yaxt.h>
#define VERBOSE
#include "tests.h"
#include "ctest_common.h"
#include "test_idxlist_utils.h"
static void
test_intersection(int num_idx_a, const Xt_int index_vector_a[],
int num_idx_b, const Xt_int index_vector_b[],
int num_idx_isect, const Xt_int index_vector_isect[]);
static void
test_idxvec_from_stripes(int num_stripes, const struct Xt_stripe stripes[],
int num_ref_indices, const Xt_int ref_indices[]);
static void
test_get_indices_at_positions(int num_idx, const Xt_int indices[],
Xt_int undef_idx,
int num_pos, const int pos[]);
int main(int argc, char **argv) {
test_init_mpi(&argc, &argv, MPI_COMM_WORLD);
{ // test packing and unpacking of index vectors
static const Xt_int index_vector[] = {1,2,3,4,5,6,7};
enum { num_indices = sizeof(index_vector) / sizeof(index_vector[0]) };
// create an index vector
Xt_idxlist idxvector = xt_idxvec_new(index_vector, num_indices);
// test the generated index vector
check_idxlist(idxvector, index_vector, num_indices);
Xt_idxlist idxvector_copy = idxlist_pack_unpack_copy(idxvector);
// check the received index vector
check_idxlist(idxvector_copy, index_vector, num_indices);
// compute intersection between the two index vectors
Xt_idxlist intersection
= xt_idxlist_get_intersection(idxvector, idxvector_copy);
// check the computed intersection (should be identically to the original
// index vector)
check_idxlist(intersection, index_vector, num_indices);
// check the conversion to stripes
struct Xt_stripe *stripes;
int num_stripes;
xt_idxlist_get_index_stripes(idxvector, &stripes, &num_stripes);
static const struct Xt_stripe ref_stripes[]
= {{.start = 1, .stride = 1, .nstrides = 7}};
enum { ref_num_stripes = sizeof (ref_stripes) / sizeof (ref_stripes[0]) };
check_stripes(stripes, num_stripes, ref_stripes, ref_num_stripes);
// clean up
free(stripes);
xt_idxlist_delete(idxvector);
xt_idxlist_delete(idxvector_copy);
xt_idxlist_delete(intersection);
}
{ // test copying of index vector
static const Xt_int index_vector[] = {1,2,3,4,5,6,7};
enum { num_indices = sizeof(index_vector) / sizeof(index_vector[0]) };
// create an index vector
Xt_idxlist idxvector = xt_idxvec_new(index_vector, num_indices);
// test the generated index vector
check_idxlist(idxvector, index_vector, num_indices);
// copy the index vector
Xt_idxlist idxvector_copy = xt_idxlist_copy(idxvector);
// check the generated copy
check_idxlist(idxvector_copy, index_vector, num_indices);
// clean up
xt_idxlist_delete(idxvector);
xt_idxlist_delete(idxvector_copy);
}
{ // test repeated equal indices
static const Xt_int index_vector[] = {1,2,3,7,5,6,7,7};
enum { num_indices = sizeof(index_vector) / sizeof(index_vector[0]) };
// create an index vector
Xt_idxlist idxvector = xt_idxvec_new(index_vector, num_indices);
// test the generated index vector
check_idxlist(idxvector, index_vector, num_indices);
// clean up
xt_idxlist_delete(idxvector);
}
{ // subtest from test_ut
enum { single_match_only = 1 };
static const Xt_int index_vector[]
= { 10, 15, 14, 13, 12, 15, 10, 11, 12, 13, 23, 18, 19,
20, 21, 31, 26, 27, 28, 29 };
static const Xt_int intersection_vector[]
= { 12, 12, 13, 13, 14, 15, 15, 20, 21, 23, 28, 29, 31 };
enum {
index_num = sizeof(index_vector) / sizeof(index_vector[0]),
intersection_num
= sizeof(intersection_vector) / sizeof(intersection_vector[0]),
};
// create an index vector
Xt_idxlist idxvector = xt_idxvec_new(index_vector, index_num);
// get positions:
int intersection_pos[intersection_num];
static const int ref_intersection_pos[]
= { 4, 8, 3, 9, 2, 1, 5, 13, 14, 10, 18, 19, 15 };
enum {
ref_intersection_num
= sizeof(ref_intersection_pos) / sizeof(ref_intersection_pos[0])
};
assert((int)intersection_num == (int)ref_intersection_num);
int retval = xt_idxlist_get_positions_of_indices(idxvector,
intersection_vector,
intersection_num,
intersection_pos,
single_match_only);
assert(retval == 0);
// check positions:
check_offsets(intersection_num, intersection_pos, ref_intersection_pos);
// clean up
xt_idxlist_delete(idxvector);
}
{
enum {
num_vec = 2,
num_idx = 3,
};
// check intersection
static Xt_int index_vector[num_vec][num_idx] = {{1,2,3},{1,2,3}};
test_intersection(num_idx, index_vector[0],
num_idx, index_vector[1],
num_idx, index_vector[0]);
}
{
enum {
num_vec = 2,
num_idx = 3,
};
// check intersection
static const Xt_int index_vector[num_vec][num_idx] = {{1,2,3},{2,3,4}};
static const Xt_int ref_intersection_indices[] = {2,3};
enum {
num_ref_intersection_indices
= sizeof(ref_intersection_indices) / sizeof(ref_intersection_indices[0])
};
test_intersection(num_idx, index_vector[0],
num_idx, index_vector[1],
num_ref_intersection_indices, ref_intersection_indices);
}
{
enum {
num_vec = 2,
num_idx = 3
};
// check intersection
static const Xt_int index_vector[num_vec][num_idx] = {{2,3,4},{1,2,3}};
static const Xt_int ref_intersection_indices[] = {2,3};
enum {
num_ref_intersection_indices
= sizeof(ref_intersection_indices) / sizeof(ref_intersection_indices[0])
};
test_intersection(num_idx, index_vector[0],
num_idx, index_vector[1],
num_ref_intersection_indices, ref_intersection_indices);
}
{
enum {
num_vec = 2,
num_idx = 3
};
// check intersection
static const Xt_int index_vector[num_vec][num_idx] = {{4,2,3},{3,1,2}};
static const Xt_int ref_intersection_indices[] = {2,3};
enum {
num_ref_intersection_indices
= sizeof(ref_intersection_indices) / sizeof(ref_intersection_indices[0])
};
test_intersection(num_idx, index_vector[0],
num_idx, index_vector[1],
num_ref_intersection_indices, ref_intersection_indices);
}
{
enum {
num_vec = 2,
num_idx = 3
};
// check intersection
static const Xt_int index_vector[2][3] = {{3,1,2},{4,2,3}};
static const Xt_int ref_intersection_indices[] = {2,3};
enum {
num_ref_intersection_indices
= sizeof(ref_intersection_indices) / sizeof(ref_intersection_indices[0])
};
test_intersection(num_idx, index_vector[0],
num_idx, index_vector[1],
num_ref_intersection_indices, ref_intersection_indices);
}
{
// test constructor xt_idxvec_from_stripes_new
static const struct Xt_stripe stripes[]
= {{.start = 5, .stride = 1, .nstrides = 5},
{.start = 4, .stride = -1, .nstrides = 5}};
static const Xt_int ref_indices[] = {5,6,7,8,9,4,3,2,1,0};
enum {
num_stripes = sizeof (stripes) / sizeof (stripes[0]),
num_ref_indices = sizeof (ref_indices) / sizeof (ref_indices[0]),
};
test_idxvec_from_stripes(num_stripes, stripes,
num_ref_indices, ref_indices);
}
{
// test constructor xt_idxvec_from_stripes_new
static const struct Xt_stripe stripes[]
= {{.start = 0, .stride = 1, .nstrides = 5},
{.start = 2, .stride = 1, .nstrides = 5},
{.start = 4, .stride = 1, .nstrides = 5}};
static const Xt_int ref_indices[]
= { 0, 1, 2, 3, 4, 2, 3, 4, 5, 6, 4, 5, 6, 7, 8 };
enum {
num_stripes = sizeof (stripes) / sizeof (stripes[0]),
num_ref_indices = sizeof (ref_indices) / sizeof (ref_indices[0])
};
test_idxvec_from_stripes(num_stripes, stripes,
num_ref_indices, ref_indices);
}
{
// test constructor xt_idxvec_from_stripes_new
static const struct Xt_stripe stripes[]
= {{.start = 2, .stride = 1, .nstrides = 5},
{.start = 0, .stride = 1, .nstrides = 5},
{.start = 4, .stride = 1, .nstrides = 5}};
static const Xt_int ref_indices[]
= { 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 4, 5, 6, 7, 8 };
enum {
num_stripes = sizeof (stripes) / sizeof (stripes[0]),
num_ref_indices = sizeof (ref_indices) / sizeof (ref_indices[0])
};
test_idxvec_from_stripes(num_stripes, stripes,
num_ref_indices, ref_indices);
}
{
// test constructor xt_idxvec_from_stripes_new
static const struct Xt_stripe stripes[]
= {{.start = 2, .stride = 1, .nstrides = 5},
{.start = 4, .stride = -1, .nstrides = 5},
{.start = 4, .stride = 1, .nstrides = 5}};
static const Xt_int ref_indices[]
= { 2, 3, 4, 5, 6, 4, 3, 2, 1, 0, 4, 5, 6, 7, 8 };
enum {
num_stripes = sizeof (stripes) / sizeof (stripes[0]),
num_ref_indices = sizeof (ref_indices) / sizeof (ref_indices[0])
};
test_idxvec_from_stripes(num_stripes, stripes,
num_ref_indices, ref_indices);
}
{
// test constructor xt_idxvec_from_stripes_new
static const struct Xt_stripe stripes[]
= {{.start = 0, .stride = 3, .nstrides = 5},
{.start = 1, .stride = 3, .nstrides = 5},
{.start = 14, .stride = -3, .nstrides = 5}};
static const Xt_int ref_indices[]
= { 0, 3, 6, 9, 12, 1, 4, 7, 10, 13, 14, 11, 8, 5, 2 };
enum {
num_stripes = sizeof (stripes) / sizeof (stripes[0]),
num_ref_indices = sizeof (ref_indices) / sizeof (ref_indices[0])
};
test_idxvec_from_stripes(num_stripes, stripes,
num_ref_indices, ref_indices);
}
{
// test constructor xt_idxvec_from_stripes_new
static const struct Xt_stripe stripes[]
= {{.start = 0, .stride = 3, .nstrides = 5},
{.start = 2, .stride = 3, .nstrides = 5},
{.start = 14, .stride = -3, .nstrides = 5}};
static const Xt_int ref_indices[]
= { 0, 3, 6, 9, 12, 2, 5, 8, 11, 14, 14, 11, 8, 5, 2 };
enum {
num_stripes = sizeof (stripes) / sizeof (stripes[0]),
num_ref_indices = sizeof (ref_indices) / sizeof (ref_indices[0])
};
test_idxvec_from_stripes(num_stripes, stripes,
num_ref_indices, ref_indices);
}
{
// test constructor xt_idxvec_from_stripes_new
static const struct Xt_stripe stripes[]
= {{.start = 0, .stride = -1, .nstrides = 5},
{.start = 1, .stride = 1, .nstrides = 5},
{.start = -5, .stride = -1, .nstrides = 5},
{.start = 6, .stride = 1, .nstrides = 5}};
static const Xt_int ref_indices[]
= { 0, -1, -2, -3, -4, 1, 2, 3, 4, 5,
-5, -6, -7, -8, -9, 6, 7, 8, 9, 10 };
enum {
num_stripes = sizeof (stripes) / sizeof (stripes[0]),
num_ref_indices = sizeof (ref_indices) / sizeof (ref_indices[0])
};
test_idxvec_from_stripes(num_stripes, stripes,
num_ref_indices, ref_indices);
}
{
// check idxvec_get_indices_at_positions
// case: mixed valid and invalid positions
Xt_int undef_idx = XT_INT_MIN;
static const Xt_int indices[]
= { 0, 3, 6, 9, 12, 1, 4, 7, 10, 13, 14, 11, 8, 5, 2, 1 };
static const int pos[]
= { 0, 2, 7, 9, 11, 100, 11, 200, 9, 300, 7, 400, 5 };
enum {
num_indices = sizeof(indices) / sizeof(indices[0]),
num_pos = sizeof(pos) / sizeof(pos[0]),
};
test_get_indices_at_positions(num_indices, indices, undef_idx,
num_pos, pos);
}
{
// check idxvec_get_indices_at_positions
// case: only valid positions
Xt_int undef_idx = XT_INT_MIN;
static const Xt_int indices[]
= { 0, 3, 6, 9, 12, 1, 4, 7, 10, 13, 14, 11, 8, 5, 2, 1 };
static const int pos[]
= { 0, 2, 7, 9, 11, 11, 9, 7, 5 };
enum {
num_indices = sizeof(indices) / sizeof(indices[0]),
num_pos = sizeof(pos) / sizeof(pos[0]),
};
test_get_indices_at_positions(num_indices, indices, undef_idx,
num_pos, pos);
}
{
// check idxvec_get_indices_at_positions
// case: only invalid positions
Xt_int undef_idx = XT_INT_MIN;
static const Xt_int indices[]
= { 0, 3, 6, 9, 12, 1, 4, 7, 10, 13, 14, 11, 8, 5, 2, 1 };
static const int pos[]
= { 100, 102, 107, 109, 1011, 1011, 109, 107, 105 };
enum {
num_indices = sizeof(indices) / sizeof(indices[0]),
num_pos = sizeof(pos) / sizeof(pos[0]),
};
test_get_indices_at_positions(num_indices, indices, undef_idx,
num_pos, pos);
}
{
// check get_positions_of_indices
// case: some unmatched indices
enum { num_indices = 2 };
static const Xt_int indices[num_indices] = { 0, 2 };
Xt_idxlist idxvec = xt_idxvec_new(indices, num_indices);
int position;
if (!xt_idxlist_get_position_of_index(idxvec, 1, &position))
PUT_ERR("xt_idxlist_get_position_of_index did not return an error\n");
if (!xt_idxlist_get_position_of_index_off(idxvec, 1, &position, 0))
PUT_ERR("xt_idxlist_get_position_of_index_off"
" did not return an error\n");
if (!xt_idxlist_get_position_of_index_off(idxvec, 0, &position, 1))
PUT_ERR("xt_idxlist_get_position_of_index_off"
" did not return an error\n");
static const Xt_int selection[] = { 1, 2, 3 };
enum { num_selection = (int)(sizeof(selection) / sizeof(*selection)) };
int positions[num_selection];
static const int ref_positions[] = { -1, 1, -1 };
if (xt_idxlist_get_positions_of_indices(idxvec, selection, num_selection,
positions, 0) != 2)
PUT_ERR("xt_idxlist_get_position_of_indices did not return correct num_unmatched\n");
bool mismatch = false;
for (size_t i = 0; i < num_selection; i++)
mismatch |= (positions[i] != ref_positions[i]);
if (mismatch)
PUT_ERR("xt_idxlist_get_position_of_indices did not return correct"
" position\n");
}
{
// check get_bounding_box
static const Xt_int indices[2] = {21,42};
int num_indices = 2;
Xt_idxlist idxvec = xt_idxvec_new(indices, num_indices);
enum { ndim = 3 };
static const Xt_int global_size[ndim] = { 4, 4, 4 };
Xt_int global_start_index = 0;
struct Xt_bounds bounds[ndim];
xt_idxlist_get_bounding_box(idxvec, ndim, global_size,
global_start_index, bounds);
bool mismatch = false;
for (unsigned i = 0; i < ndim; ++i)
mismatch |= (bounds[i].size != 2 || bounds[i].start != 1);
if (mismatch)
PUT_ERR("ERROR: xt_idxlist_get_bounding_box\n");
}
{
// check get_bounding_box
Xt_int indices[5] = {45,35,32,48,33};
int num_indices = 5;
Xt_idxlist idxvec = xt_idxvec_new(indices, num_indices);
enum { ndim = 3 };
static const Xt_int global_size[ndim] = { 5, 4, 3 };
Xt_int global_start_index = 1;
struct Xt_bounds bounds[ndim];
xt_idxlist_get_bounding_box(idxvec, ndim, global_size,
global_start_index, bounds);
static const Xt_int ref_start[3] = {2,2,1};
bool mismatch = false;
for (size_t i = 0; i < ndim; ++i)
mismatch |= (bounds[i].size != 2 || bounds[i].start != ref_start[i]);
if (mismatch)
PUT_ERR("ERROR: xt_idxlist_get_bounding_box\n");
}
{
// check get_bounding_box
static const Xt_int indices[1] = {-1};
int num_indices = 0;
Xt_idxlist idxvec = xt_idxvec_new(indices, num_indices);
enum { ndim = 3 };
static const Xt_int global_size[ndim] = { 4, 4, 4 };
Xt_int global_start_index = 0;
struct Xt_bounds bounds[ndim];
xt_idxlist_get_bounding_box(idxvec, ndim, global_size,
global_start_index, bounds);
bool mismatch = false;
for (size_t i = 0; i < ndim; ++i)
mismatch |= (bounds[i].size != 0);
if (mismatch)
PUT_ERR("ERROR: xt_idxlist_get_bounding_box\n");
}
MPI_Finalize();
return TEST_EXIT_CODE;
}
static Xt_idxlist
setup_idxvec(int num_idx, const Xt_int indices[])
{
Xt_idxlist idxvec = xt_idxvec_new(indices, num_idx);
check_idxlist(idxvec, indices, num_idx);
return idxvec;
}
static void
test_intersection(int num_idx_a, const Xt_int index_vector_a[],
int num_idx_b, const Xt_int index_vector_b[],
int num_idx_isect, const Xt_int index_vector_isect[])
{
Xt_idxlist idxvec_a = setup_idxvec(num_idx_a, index_vector_a),
idxvec_b = setup_idxvec(num_idx_b, index_vector_b),
intersection = xt_idxlist_get_intersection(idxvec_a, idxvec_b);
check_idxlist(intersection, index_vector_isect, num_idx_isect);
Xt_idxlist temp[3] = { idxvec_a, idxvec_b, intersection };
for (size_t i = 0; i < 3; ++i)
}
static void
test_idxvec_from_stripes(int num_stripes, const struct Xt_stripe stripes[],
int num_ref_indices, const Xt_int ref_indices[])
{
Xt_idxlist idxvec = xt_idxvec_from_stripes_new(stripes, num_stripes);
check_idxlist(idxvec, ref_indices, num_ref_indices);
}
static void
test_get_indices_at_positions(int num_indices, const Xt_int *indices,
Xt_int undef_idx,
int num_pos, const int *pos)
{
Xt_idxlist idxvec = xt_idxvec_new(indices, num_indices);
int ref_undef_count = 0;
num_pos = num_pos < 0 ? 0 : num_pos;
Xt_int ref_sel_idx[num_pos];
for (size_t i = 0; i < (size_t)num_pos; i++) {
int p = pos[i];
if (xt_idxlist_get_index_at_position(idxvec, p, &ref_sel_idx[i]) != 0) {
ref_sel_idx[i] = undef_idx;
ref_undef_count++;
}
}
Xt_int sel_idx[num_pos];
int undef_count
= xt_idxlist_get_indices_at_positions(idxvec, pos, num_pos, sel_idx,
undef_idx);
if (undef_count != ref_undef_count)
PUT_ERR("test_idxvec.c: undef_count != ref_undef_count\n");
bool mismatch = false;
for (size_t i = 0; i < (size_t)num_pos; i++)
mismatch |= (sel_idx[i] != ref_sel_idx[i]);
if (mismatch)
PUT_ERR("test_idxvec.c: sel_idx != ref_sel_idx\n");
}
/*
* Local Variables:
* c-basic-offset: 2
* coding: utf-8
* indent-tabs-mode: nil
* show-trailing-whitespace: t
* require-trailing-newline: t
* End:
*/
@ MPI_COMM_WORLD
Definition core.h:73
add versions of standard API functions not returning on error
Xt_int start
Definition xt_idxlist.h:67
Xt_int size
Definition xt_idxlist.h:67
Xt_int start
Definition xt_stripe.h:55
void xt_initialize(MPI_Comm default_comm)
Definition xt_init.c:70
#define XT_INT_MIN
Definition xt_core.h:78
void xt_finalize(void)
Definition xt_init.c:92
XT_INT Xt_int
Definition xt_core.h:72
int xt_idxlist_get_positions_of_indices(Xt_idxlist idxlist, const Xt_int *indices, int num_indices, int *positions, int single_match_only)
Definition xt_idxlist.c:221
int xt_idxlist_get_index_at_position(Xt_idxlist idxlist, int position, Xt_int *index)
Definition xt_idxlist.c:176
int xt_idxlist_get_position_of_index_off(Xt_idxlist idxlist, Xt_int index, int *position, int offset)
Definition xt_idxlist.c:306
int xt_idxlist_get_indices_at_positions(Xt_idxlist idxlist, const int *positions, int num_pos, Xt_int *indices, Xt_int undef_idx)
Definition xt_idxlist.c:183
void xt_idxlist_get_index_stripes(Xt_idxlist idxlist, struct Xt_stripe **stripes, int *num_stripes)
Definition xt_idxlist.c:135
void xt_idxlist_get_bounding_box(Xt_idxlist idxlist, unsigned ndim, const Xt_int global_size[ndim], Xt_int global_start_index, struct Xt_bounds bounds[ndim])
Definition xt_idxlist.c:379
Xt_idxlist xt_idxlist_get_intersection(Xt_idxlist idxlist_src, Xt_idxlist idxlist_dst)
Xt_idxlist xt_idxlist_copy(Xt_idxlist idxlist)
Definition xt_idxlist.c:94
int xt_idxlist_get_position_of_index(Xt_idxlist idxlist, Xt_int index, int *position)
Definition xt_idxlist.c:214
void xt_idxlist_delete(Xt_idxlist idxlist)
Definition xt_idxlist.c:75
Xt_idxlist xt_idxvec_from_stripes_new(const struct Xt_stripe *stripes, int num_stripes)
Xt_idxlist xt_idxvec_new(const Xt_int *idxlist, int num_indices)
Definition xt_idxvec.c:212