/* * Copyright (c) 2017 Intel Corporation. All rights reserved. * Copyright (c) 2016, Cisco Systems, Inc. All rights reserved. * * This software is available to you under the BSD license below: * * 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. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include #include #include #include "ofi_atomic.h" #include "fabtest.h" static int alph_index = 0; static const char integ_alphabet[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; static const int integ_alphabet_length = (sizeof(integ_alphabet)/sizeof(*integ_alphabet)) - 1; #define CHECK_LOCAL(res,local,cnt,ret,TYPE) \ do { \ int i; \ TYPE *r = (res); \ TYPE *l = (local); \ for (i = 0; i < cnt; i++) { \ if (r[i] != l[i]) { \ ret = -FI_EIO; \ break; \ } \ } \ } while (0) \ #define FT_FILL(dst,cnt,TYPE) \ do { \ int i; \ TYPE *d = (dst); \ for (i = 0; i < cnt; i++) { \ d[i] = (TYPE) (integ_alphabet[alph_index++]); \ if (alph_index >= integ_alphabet_length) \ alph_index = 0; \ } \ } while (0) #define SWITCH_TYPES(type,FUNC,...) \ switch (type) { \ case FI_INT8: FUNC(__VA_ARGS__,int8_t); break; \ case FI_UINT8: FUNC(__VA_ARGS__,uint8_t); break; \ case FI_INT16: FUNC(__VA_ARGS__,int16_t); break; \ case FI_UINT16: FUNC(__VA_ARGS__,uint16_t); break; \ case FI_INT32: FUNC(__VA_ARGS__,int32_t); break; \ case FI_UINT32: FUNC(__VA_ARGS__,uint32_t); break; \ case FI_INT64: FUNC(__VA_ARGS__,int64_t); break; \ case FI_UINT64: FUNC(__VA_ARGS__,uint64_t); break; \ case FI_FLOAT: FUNC(__VA_ARGS__,float); break; \ case FI_DOUBLE: FUNC(__VA_ARGS__,double); break; \ case FI_LONG_DOUBLE: FUNC(__VA_ARGS__,long_double); break; \ case FI_FLOAT_COMPLEX: FUNC(__VA_ARGS__,ofi_complex_float); break; \ case FI_DOUBLE_COMPLEX: FUNC(__VA_ARGS__,ofi_complex_double); break; \ case FI_LONG_DOUBLE_COMPLEX: FUNC(__VA_ARGS__,ofi_complex_long_double); break;\ default: return -FI_EOPNOTSUPP; \ } int ft_sync_fill_bufs(size_t size) { ft_sock_sync(0); if (test_info.caps & FI_ATOMIC) { SWITCH_TYPES(ft_atom_ctrl.datatype, FT_FILL, ft_tx_ctrl.buf, ft_atom_ctrl.count); SWITCH_TYPES(ft_atom_ctrl.datatype, FT_FILL, ft_mr_ctrl.buf, ft_atom_ctrl.count); memcpy(ft_atom_ctrl.orig_buf, ft_mr_ctrl.buf, size); memcpy(ft_tx_ctrl.cpy_buf, ft_tx_ctrl.buf, size); } else if (is_read_func(test_info.class_function)) { ft_fill_buf(ft_mr_ctrl.buf, size); } else { ft_fill_buf(ft_tx_ctrl.buf, size); memcpy(ft_tx_ctrl.cpy_buf, ft_tx_ctrl.buf, size); } ft_sock_sync(0); return 0; } static int verify_atomic(void) { int ret = 0; void *dst, *src, *cmp, *tmp, *res; enum fi_datatype type; enum fi_op op; size_t count; dst = ft_atom_ctrl.orig_buf; src = ft_tx_ctrl.cpy_buf; cmp = ft_atom_ctrl.comp_buf; tmp = ft_rx_ctrl.buf; res = ft_atom_ctrl.res_buf; type = ft_atom_ctrl.datatype; op = ft_atom_ctrl.op; count = ft_atom_ctrl.count; if (is_fetch_func(test_info.class_function) || is_compare_func(test_info.class_function)) { SWITCH_TYPES(type, CHECK_LOCAL, dst, res, count, ret); if (ret) return ret; } if (is_compare_func(test_info.class_function)) { ofi_atomic_swap_handlers[op - OFI_SWAP_OP_START][type](dst, src, cmp, tmp, count); } else if (is_fetch_func(test_info.class_function)) { ofi_atomic_readwrite_handlers[op][type](dst, src, tmp, count); } else { ofi_atomic_write_handlers[op][type](dst, src, count); } SWITCH_TYPES(type, CHECK_LOCAL, dst, ft_mr_ctrl.buf, count, ret); return ret; } int ft_verify_bufs() { char *compare_buf; size_t compare_size; if (test_info.caps & FI_ATOMIC) return verify_atomic(); if (test_info.caps & FI_RMA) { compare_size = ft_tx_ctrl.rma_msg_size; if (is_read_func(test_info.class_function)) compare_buf = (char *) ft_tx_ctrl.buf; else compare_buf = (char *) ft_mr_ctrl.buf; } else { compare_size = ft_tx_ctrl.msg_size; compare_buf = (char *) ft_rx_ctrl.buf; } return ft_check_buf(compare_buf, compare_size) ? -FI_EIO : 0; } void ft_verify_comp(void *buf) { struct fi_cq_data_entry *comp; if (ft_rx_ctrl.cq_format != FI_CQ_FORMAT_DATA) return; comp = (struct fi_cq_data_entry *) buf; if (comp->flags & FI_REMOTE_CQ_DATA) { if (comp->data == ft_tx_ctrl.remote_cq_data) ft_ctrl.verify_cnt++; } }