1 /*********************************************************************
2 Blosc - Blocked Shuffling and Compression Library
3
4 Roundtrip tests for the ALTIVEC-accelerated shuffle/unshuffle.
5
6 Copyright (C) 2021 The Blosc Developers <blosc@blosc.org>
7 https://blosc.org
8 License: BSD 3-Clause (see LICENSE.txt)
9
10 See LICENSE.txt for details about copyright and rights to use.
11 **********************************************************************/
12
13 #include "test_common.h"
14 #include "../blosc/shuffle.h"
15 #include "../blosc/shuffle-generic.h"
16
17
18 /* Include ALTIVEC-accelerated shuffle implementation if supported by this compiler.
19 TODO: Need to also do run-time CPU feature support here. */
20 #if defined(SHUFFLE_ALTIVEC_ENABLED)
21 #include "../blosc/shuffle-altivec.h"
22 #else
23 #if defined(_MSC_VER)
24 #pragma message("ALTIVEC shuffle tests not enabled.")
25 #else
26 #warning ALTIVEC shuffle tests not enabled.
27 #endif
28 #endif /* defined(SHUFFLE_ALTIVEC_ENABLED) */
29
30
31 /** Roundtrip tests for the ALTIVEC-accelerated shuffle/unshuffle. */
test_shuffle_roundtrip_altivec(int32_t type_size,int32_t num_elements,size_t buffer_alignment,int test_type)32 static int test_shuffle_roundtrip_altivec(int32_t type_size, int32_t num_elements,
33 size_t buffer_alignment, int test_type) {
34 #if defined(SHUFFLE_ALTIVEC_ENABLED)
35 int32_t buffer_size = type_size * num_elements;
36
37 /* Allocate memory for the test. */
38 void* original = blosc_test_malloc(buffer_alignment, (size_t)buffer_size);
39 void* shuffled = blosc_test_malloc(buffer_alignment, (size_t)buffer_size);
40 void* unshuffled = blosc_test_malloc(buffer_alignment, (size_t)buffer_size);
41
42 /* Fill the input data buffer with random values. */
43 blosc_test_fill_seq(original, (size_t)buffer_size);
44
45 /* Shuffle/unshuffle, selecting the implementations based on the test type. */
46 switch (test_type) {
47 case 0:
48 /* altivec/altivec */
49 shuffle_altivec(type_size, buffer_size, original, shuffled);
50 unshuffle_altivec(type_size, buffer_size, shuffled, unshuffled);
51 break;
52 case 1:
53 /* generic/altivec */
54 shuffle_generic(type_size, buffer_size, original, shuffled);
55 unshuffle_altivec(type_size, buffer_size, shuffled, unshuffled);
56 break;
57 case 2:
58 /* altivec/generic */
59 shuffle_altivec(type_size, buffer_size, original, shuffled);
60 unshuffle_generic(type_size, buffer_size, shuffled, unshuffled);
61 break;
62 default:
63 fprintf(stderr, "Invalid test type specified (%d).", test_type);
64 return EXIT_FAILURE;
65 }
66
67 /* The round-tripped data matches the original data when the
68 result of memcmp is 0. */
69 int exit_code = memcmp(original, unshuffled, (size_t)buffer_size) ?
70 EXIT_FAILURE : EXIT_SUCCESS;
71
72 /* Free allocated memory. */
73 blosc_test_free(original);
74 blosc_test_free(shuffled);
75 blosc_test_free(unshuffled);
76
77 return exit_code;
78 #else
79 return EXIT_SUCCESS;
80 #endif /* defined(SHUFFLE_ALTIVEC_ENABLED) */
81 }
82
83
84 /** Required number of arguments to this test, including the executable name. */
85 #define TEST_ARG_COUNT 5
86
main(int argc,char ** argv)87 int main(int argc, char** argv) {
88 /* argv[1]: sizeof(element type)
89 argv[2]: number of elements
90 argv[3]: buffer alignment
91 argv[4]: test type
92 */
93
94 /* Verify the correct number of command-line args have been specified. */
95 if (TEST_ARG_COUNT != argc) {
96 blosc_test_print_bad_argcount_msg(TEST_ARG_COUNT, argc);
97 return EXIT_FAILURE;
98 }
99
100 /* Parse arguments */
101 uint32_t type_size;
102 if (!blosc_test_parse_uint32_t(argv[1], &type_size) || (type_size < 1)) {
103 blosc_test_print_bad_arg_msg(1);
104 return EXIT_FAILURE;
105 }
106
107 uint32_t num_elements;
108 if (!blosc_test_parse_uint32_t(argv[2], &num_elements) || (num_elements < 1)) {
109 blosc_test_print_bad_arg_msg(2);
110 return EXIT_FAILURE;
111 }
112
113 uint32_t buffer_align_size;
114 if (!blosc_test_parse_uint32_t(argv[3], &buffer_align_size)
115 || (buffer_align_size & (buffer_align_size - 1))
116 || (buffer_align_size < sizeof(void*))) {
117 blosc_test_print_bad_arg_msg(3);
118 return EXIT_FAILURE;
119 }
120
121 uint32_t test_type;
122 if (!blosc_test_parse_uint32_t(argv[4], &test_type) || (test_type > 2)) {
123 blosc_test_print_bad_arg_msg(4);
124 return EXIT_FAILURE;
125 }
126
127 /* Run the test. */
128 return test_shuffle_roundtrip_altivec(type_size, num_elements, buffer_align_size, test_type);
129 }
130