1/* 2 * Copyright (C) by Argonne National Laboratory 3 * See COPYRIGHT in top-level directory 4 */ 5 6#ifndef YAKSA_H_INCLUDED 7#define YAKSA_H_INCLUDED 8 9/* Keep C++ compilers from getting confused */ 10#if defined(__cplusplus) 11/* extern "C" { */ 12#endif 13 14/* This is a public API header and should not include any internal 15 * headers */ 16#include <stdio.h> 17#include <stdint.h> 18#include <sys/types.h> 19#include <sys/uio.h> 20 21 22/******************************************************************************/ 23/* YAKSA TYPES */ 24/******************************************************************************/ 25 26/** @file yaksa.h */ 27 28/*! \addtogroup yaksa-types Yaksa Builtin Datatypes 29 * @{ 30 */ 31 32/* The most significant 32 bits of the yaksa type are unused at this 33 * point. They are kept for future potential use, for example to set 34 * a predefined bit or to store the size or alignment for predefined 35 * types inside the handle itself. For now, only the least 36 * significant 32 bits are used to store the handle to the internal 37 * type object. */ 38typedef uint64_t yaksa_type_t; 39 40/** 41 * \brief yaksa builtin datatypes 42 */ 43/* generic */ 44#define YAKSA_TYPE__NULL ((yaksa_type_t) 0) 45#define YAKSA_TYPE___BOOL ((yaksa_type_t) 1) 46 47/* char types */ 48#define YAKSA_TYPE__CHAR ((yaksa_type_t) 2) 49#define YAKSA_TYPE__SIGNED_CHAR ((yaksa_type_t) 3) 50#define YAKSA_TYPE__UNSIGNED_CHAR ((yaksa_type_t) 4) 51#define YAKSA_TYPE__WCHAR_T ((yaksa_type_t) 5) 52 53/* int types */ 54#define YAKSA_TYPE__INT8_T ((yaksa_type_t) 6) 55#define YAKSA_TYPE__INT16_T ((yaksa_type_t) 7) 56#define YAKSA_TYPE__INT32_T ((yaksa_type_t) 8) 57#define YAKSA_TYPE__INT64_T ((yaksa_type_t) 9) 58#define YAKSA_TYPE__UINT8_T ((yaksa_type_t) 10) 59#define YAKSA_TYPE__UINT16_T ((yaksa_type_t) 11) 60#define YAKSA_TYPE__UINT32_T ((yaksa_type_t) 12) 61#define YAKSA_TYPE__UINT64_T ((yaksa_type_t) 13) 62 63#define YAKSA_TYPE__INT ((yaksa_type_t) 14) 64#define YAKSA_TYPE__UNSIGNED ((yaksa_type_t) 15) 65#define YAKSA_TYPE__SHORT ((yaksa_type_t) 16) 66#define YAKSA_TYPE__UNSIGNED_SHORT ((yaksa_type_t) 17) 67#define YAKSA_TYPE__LONG ((yaksa_type_t) 18) 68#define YAKSA_TYPE__UNSIGNED_LONG ((yaksa_type_t) 19) 69#define YAKSA_TYPE__LONG_LONG ((yaksa_type_t) 20) 70#define YAKSA_TYPE__UNSIGNED_LONG_LONG ((yaksa_type_t) 21) 71 72#define YAKSA_TYPE__INT_FAST8_T ((yaksa_type_t) 22) 73#define YAKSA_TYPE__INT_FAST16_T ((yaksa_type_t) 23) 74#define YAKSA_TYPE__INT_FAST32_T ((yaksa_type_t) 24) 75#define YAKSA_TYPE__INT_FAST64_T ((yaksa_type_t) 25) 76#define YAKSA_TYPE__UINT_FAST8_T ((yaksa_type_t) 26) 77#define YAKSA_TYPE__UINT_FAST16_T ((yaksa_type_t) 27) 78#define YAKSA_TYPE__UINT_FAST32_T ((yaksa_type_t) 28) 79#define YAKSA_TYPE__UINT_FAST64_T ((yaksa_type_t) 29) 80 81#define YAKSA_TYPE__INT_LEAST8_T ((yaksa_type_t) 30) 82#define YAKSA_TYPE__INT_LEAST16_T ((yaksa_type_t) 31) 83#define YAKSA_TYPE__INT_LEAST32_T ((yaksa_type_t) 32) 84#define YAKSA_TYPE__INT_LEAST64_T ((yaksa_type_t) 33) 85#define YAKSA_TYPE__UINT_LEAST8_T ((yaksa_type_t) 34) 86#define YAKSA_TYPE__UINT_LEAST16_T ((yaksa_type_t) 35) 87#define YAKSA_TYPE__UINT_LEAST32_T ((yaksa_type_t) 36) 88#define YAKSA_TYPE__UINT_LEAST64_T ((yaksa_type_t) 37) 89 90#define YAKSA_TYPE__BYTE ((yaksa_type_t) 38) 91#define YAKSA_TYPE__INTMAX_T ((yaksa_type_t) 39) 92#define YAKSA_TYPE__UINTMAX_T ((yaksa_type_t) 40) 93 94#define YAKSA_TYPE__SIZE_T ((yaksa_type_t) 41) 95 96/* pointer type */ 97#define YAKSA_TYPE__INTPTR_T ((yaksa_type_t) 42) 98#define YAKSA_TYPE__UINTPTR_T ((yaksa_type_t) 43) 99#define YAKSA_TYPE__PTRDIFF_T ((yaksa_type_t) 44) 100 101/* float types */ 102#define YAKSA_TYPE__FLOAT ((yaksa_type_t) 45) 103#define YAKSA_TYPE__DOUBLE ((yaksa_type_t) 46) 104#define YAKSA_TYPE__LONG_DOUBLE ((yaksa_type_t) 47) 105 106/* pair types */ 107#define YAKSA_TYPE__C_COMPLEX ((yaksa_type_t) 48) 108#define YAKSA_TYPE__C_DOUBLE_COMPLEX ((yaksa_type_t) 49) 109#define YAKSA_TYPE__C_LONG_DOUBLE_COMPLEX ((yaksa_type_t) 50) 110#define YAKSA_TYPE__FLOAT_INT ((yaksa_type_t) 51) 111#define YAKSA_TYPE__DOUBLE_INT ((yaksa_type_t) 52) 112#define YAKSA_TYPE__LONG_INT ((yaksa_type_t) 53) 113#define YAKSA_TYPE__2INT ((yaksa_type_t) 54) 114#define YAKSA_TYPE__SHORT_INT ((yaksa_type_t) 55) 115#define YAKSA_TYPE__LONG_DOUBLE_INT ((yaksa_type_t) 56) 116 117/*! @} */ 118 119 120/*! \addtogroup yaksa-requests Yaksa predefined datatypes 121 * @{ 122 */ 123 124typedef uint64_t yaksa_request_t; 125 126/** 127 * \brief yaksa predefined requests 128 */ 129#define YAKSA_REQUEST__NULL ((yaksa_request_t) 0) 130 131/*! @} */ 132 133 134/*! \addtogroup yaksa-return-codes Yaksa return codes 135 * @{ 136 */ 137 138/******************************************************************************/ 139/* YAKSA RETURN CODES */ 140/******************************************************************************/ 141/*! \brief the function completed successfully */ 142#define YAKSA_SUCCESS (0) 143/*! \brief yaksa ran out of memory */ 144#define YAKSA_ERR__OUT_OF_MEM (1) 145/*! \brief yaksa internal (undocumented) error */ 146#define YAKSA_ERR__INTERNAL (2) 147/*! \brief yaksa operation is not supported (only for development purposes) */ 148#define YAKSA_ERR__NOT_SUPPORTED (3) 149 150/*! @} */ 151 152 153/*! \addtogroup yaksa-subarray-order Yaksa subarray order 154 * @{ 155 */ 156 157/******************************************************************************/ 158/* YAKSA SUBARRAY DATA ORDER */ 159/******************************************************************************/ 160/** 161 * \brief yaksa subarray order 162 */ 163typedef enum { 164 YAKSA_SUBARRAY_ORDER__C, 165 YAKSA_SUBARRAY_ORDER__FORTRAN 166} yaksa_subarray_order_e; 167 168/*! @} */ 169 170 171/*! \addtogroup yaksa-info Yaksa info object 172 * @{ 173 */ 174 175/** 176 * \brief yaksa info object 177 */ 178typedef void *yaksa_info_t; 179 180#define YAKSA_INFO_MAX_KEYLEN (256) 181 182/*! @} */ 183 184 185/*! \addtogroup yaksa-funcs Yaksa public functions 186 * @{ 187 */ 188 189/******************************************************************************/ 190/* YAKSA PUBLIC FUNCTIONS */ 191/******************************************************************************/ 192/*! 193 * \brief creates an info object 194 * 195 * \param[out] info Info object being created 196 */ 197int yaksa_info_create(yaksa_info_t * info); 198 199/*! 200 * \brief frees the info object 201 * 202 * \param[in] info Info object being freed 203 */ 204int yaksa_info_free(yaksa_info_t info); 205 206/*! 207 * \brief append a hint to the info object 208 * 209 * \param[in] info Info object 210 * \param[in] key Hint key 211 * \param[in] val Hint value 212 * \param[in] vallen Length of the hint value 213 */ 214int yaksa_info_keyval_append(yaksa_info_t info, const char *key, const void *val, 215 unsigned int vallen); 216 217/*! 218 * \brief initializes the yaksa library 219 */ 220int yaksa_init(yaksa_info_t info); 221 222/*! 223 * \brief finalizes the yaksa library 224 */ 225int yaksa_finalize(void); 226 227/*! 228 * \brief creates a vector layout 229 * 230 * \param[in] count Number of blocks in the vector 231 * \param[in] blocklength Length of each block 232 * \param[in] stride Increment from the start of one block to another 233 * (represented in terms of the count of the oldtype) 234 * \param[in] oldtype Base datatype forming each element in the vector 235 * \param[in] info Hint object 236 * \param[out] newtype Final generated type 237 */ 238int yaksa_type_create_vector(int count, int blocklength, int stride, yaksa_type_t oldtype, 239 yaksa_info_t info, yaksa_type_t * newtype); 240 241/*! 242 * \brief creates a hvector layout 243 * 244 * \param[in] count Number of blocks in the vector 245 * \param[in] blocklength Length of each block 246 * \param[in] stride Increment from the start of one block to another 247 * (represented in bytes) 248 * \param[in] oldtype Base datatype forming each element in the vector 249 * \param[in] info Hint object 250 * \param[out] newtype Final generated type 251 */ 252int yaksa_type_create_hvector(int count, int blocklength, intptr_t stride, yaksa_type_t oldtype, 253 yaksa_info_t info, yaksa_type_t * newtype); 254 255/*! 256 * \brief creates a contig layout 257 * 258 * \param[in] count Number of elements of the oldtype 259 * \param[in] oldtype Base datatype forming each element in the contig 260 * \param[in] info Hint object 261 * \param[out] newtype Final generated type 262 */ 263int yaksa_type_create_contig(int count, yaksa_type_t oldtype, yaksa_info_t info, 264 yaksa_type_t * newtype); 265 266/*! 267 * \brief creates a copy of the oldtype 268 * 269 * \param[in] oldtype Base datatype being dup'ed 270 * \param[in] info Hint object 271 * \param[out] newtype Final generated type 272 */ 273int yaksa_type_create_dup(yaksa_type_t oldtype, yaksa_info_t info, yaksa_type_t * newtype); 274 275/*! 276 * \brief creates a block-indexed layout 277 * 278 * \param[in] count Number of blocks in the new type 279 * \param[in] blocklength Length of each block 280 * \param[in] array_of_displacements Starting offset to each block 281 * (represented in terms of the count of the oldtype) 282 * \param[in] oldtype Base datatype forming each element in the new type 283 * \param[in] info Hint object 284 * \param[out] newtype Final generated type 285 */ 286int yaksa_type_create_indexed_block(int count, int blocklength, const int *array_of_displacements, 287 yaksa_type_t oldtype, yaksa_info_t info, 288 yaksa_type_t * newtype); 289 290/*! 291 * \brief creates a block-hindexed layout 292 * 293 * \param[in] count Number of blocks in the new type 294 * \param[in] blocklength Length of each block 295 * \param[in] array_of_displacements Starting offset to each block 296 * (represented in bytes) 297 * \param[in] oldtype Base datatype forming each element in the new type 298 * \param[in] info Hint object 299 * \param[out] newtype Final generated type 300 */ 301int yaksa_type_create_hindexed_block(int count, int blocklength, 302 const intptr_t * array_of_displacements, yaksa_type_t oldtype, 303 yaksa_info_t info, yaksa_type_t * newtype); 304 305/*! 306 * \brief creates a indexed layout 307 * 308 * \param[in] count Number of blocks in the new type 309 * \param[in] array_of_blocklengths Array of lengths of each block 310 * \param[in] array_of_displacements Starting offset to each block 311 * (represented in terms of the count of the oldtype) 312 * \param[in] oldtype Base datatype forming each element in the new type 313 * \param[in] info Hint object 314 * \param[out] newtype Final generated type 315 */ 316int yaksa_type_create_indexed(int count, const int *array_of_blocklengths, 317 const int *array_of_displacements, yaksa_type_t oldtype, 318 yaksa_info_t info, yaksa_type_t * newtype); 319 320/*! 321 * \brief creates a hindexed layout 322 * 323 * \param[in] count Number of blocks in the new type 324 * \param[in] array_of_blocklengths Array of lengths of each block 325 * \param[in] array_of_displacements Starting offset to each block 326 * (represented in bytes) 327 * \param[in] oldtype Base datatype forming each element in the new type 328 * \param[in] info Hint object 329 * \param[out] newtype Final generated type 330 */ 331int yaksa_type_create_hindexed(int count, const int *array_of_blocklengths, 332 const intptr_t * array_of_displacements, yaksa_type_t oldtype, 333 yaksa_info_t info, yaksa_type_t * newtype); 334 335/*! 336 * \brief creates a resized layout with updated lower and extent 337 * 338 * \param[in] oldtype Base datatype forming each element in the new type 339 * \param[in] lb New lower bound to use 340 * \param[in] extent New extent to use 341 * \param[in] info Hint object 342 * \param[out] newtype Final generated type 343 */ 344int yaksa_type_create_resized(yaksa_type_t oldtype, intptr_t lb, intptr_t extent, 345 yaksa_info_t info, yaksa_type_t * newtype); 346 347/*! 348 * \brief creates a struct layout 349 * 350 * \param[in] count Number of blocks in the new type 351 * \param[in] array_of_blocklengths Array of lengths of each block 352 * \param[in] array_of_displacements Starting offset to each block 353 * (represented in bytes) 354 * \param[in] array_of_types Array of base datatype forming each element in the new type 355 * \param[in] info Hint object 356 * \param[out] newtype Final generated type 357 */ 358int yaksa_type_create_struct(int count, const int *array_of_blocklengths, 359 const intptr_t * array_of_displacements, 360 const yaksa_type_t * array_of_types, yaksa_info_t info, 361 yaksa_type_t * newtype); 362 363/*! 364 * \brief creates a subarray layout 365 * 366 * \param[in] ndims Number of dimensions in the array 367 * \param[in] array_of_sizes Dimension sizes for the entire array 368 * \param[in] array_of_subsizes Dimension sizes for the subarray 369 * \param[in] array_of_starts Start location ("corner representing the start") of the subarray 370 * \param[in] order Data layout order (C or Fortran) 371 * \param[in] oldtype Base datatype forming each element in the new type 372 * \param[in] info Hint object 373 * \param[out] newtype Final generated type 374 */ 375int yaksa_type_create_subarray(int ndims, const int *array_of_sizes, const int *array_of_subsizes, 376 const int *array_of_starts, yaksa_subarray_order_e order, 377 yaksa_type_t oldtype, yaksa_info_t info, yaksa_type_t * newtype); 378 379/*! 380 * \brief gets the size of (number of bytes in) the datatype 381 * 382 * \param[in] type The datatype whose size is being requested 383 * \param[out] size The size of the datatype 384 */ 385int yaksa_type_get_size(yaksa_type_t type, uintptr_t * size); 386 387/*! 388 * \brief gets the true extent (true span) of the datatype 389 * 390 * \param[in] type The datatype whose extent is being requested 391 * \param[out] lb The lowerbound of the datatype 392 * (only used to calculate the extent; does 393 * not change where the buffer points to) 394 * \param[out] extent The extent of the datatype 395 * (represents the distance between the 396 * lowest and highest points of the datatype, 397 * which can be larger than the size of the 398 * datatype, if the layout is noncontiguous) 399 */ 400int yaksa_type_get_true_extent(yaksa_type_t type, intptr_t * lb, intptr_t * extent); 401 402/*! 403 * \brief gets the extent (span) of the datatype 404 * 405 * \param[in] type The datatype whose extent is being requested 406 * \param[out] lb The lowerbound of the datatype 407 * (only used to calculate the extent; does 408 * not change where the buffer points to) 409 * \param[out] extent The extent of the datatype 410 * (represents the distance between the 411 * lowest and highest points of the datatype. 412 * can be larger than the true extent of the 413 * datatype for subarrays or if the lb and ub 414 * values were modified by creating a resized 415 * datatype) 416 */ 417int yaksa_type_get_extent(yaksa_type_t type, intptr_t * lb, intptr_t * extent); 418 419/*! 420 * \brief frees the datatype 421 * 422 * \param[in] type The datatype being freed 423 */ 424int yaksa_type_free(yaksa_type_t type); 425 426/*! 427 * \brief tests to see if a request has completed 428 * 429 * \param[in] request The request object that needs to be tested 430 * \param[out] completed Flag to tell the caller whether the request object has completed 431 */ 432int yaksa_request_test(yaksa_request_t request, int *completed); 433 434/*! 435 * \brief waits till a request has completed 436 * 437 * \param[in] request The request object that needs to be waited up on 438 */ 439int yaksa_request_wait(yaksa_request_t request); 440 441/*! 442 * \brief packs the data represented by the (incount, type) tuple into a contiguous buffer 443 * 444 * \param[in] inbuf Input buffer from which data is being packed 445 * \param[in] incount Number of elements of the datatype representing the layout 446 * \param[in] type Datatype representing the layout 447 * \param[in] inoffset Number of bytes to skip from the layout represented by the 448 * (incount, type) tuple 449 * \param[out] outbuf Output buffer into which data is being packed 450 * \param[in] max_pack_bytes Maximum number of bytes that can be packed in the output buffer 451 * \param[out] actual_pack_bytes Actual number of bytes that were packed into the output buffer 452 * \param[in] info Hint object 453 * \param[out] request Request handle associated with the operation 454 * (YAKSA_REQUEST__NULL if the request already completed) 455 */ 456int yaksa_ipack(const void *inbuf, uintptr_t incount, yaksa_type_t type, uintptr_t inoffset, 457 void *outbuf, uintptr_t max_pack_bytes, uintptr_t * actual_pack_bytes, 458 yaksa_info_t info, yaksa_request_t * request); 459 460/*! 461 * \brief unpacks data from a contiguous buffer into a buffer represented by the (incount, type) tuple 462 * 463 * \param[in] inbuf Input buffer from which data is being unpacked 464 * \param[in] insize Number of bytes in the input buffer 465 * \param[out] outbuf Output buffer into which data is being unpacked 466 * \param[in] outcount Number of elements of the datatype representing the layout 467 * \param[in] type Datatype representing the layout 468 * \param[in] outoffset Number of bytes to skip from the layout represented by the 469 * (incount, type) tuple 470 * \param[out] actual_unpack_bytes Actual number of bytes that were unpacked into the output buffer 471 * \param[in] info Hint object 472 * \param[out] request Request handle associated with the operation 473 * (YAKSA_REQUEST__NULL if the request already completed) 474 */ 475int yaksa_iunpack(const void *inbuf, uintptr_t insize, void *outbuf, uintptr_t outcount, 476 yaksa_type_t type, uintptr_t outoffset, uintptr_t * actual_unpack_bytes, 477 yaksa_info_t info, yaksa_request_t * request); 478 479/*! 480 * \brief gets the number of contiguous segments in the (count, type) tuple 481 * 482 * \param[in] count Number of elements of the datatype representing the layout 483 * \param[in] type Datatype representing the layout 484 * \param[out] iov_len Number of contiguous segments in the (count, type) tuple 485 */ 486int yaksa_iov_len(uintptr_t count, yaksa_type_t type, uintptr_t * iov_len); 487 488/*! 489 * \brief converts the (count, type) tuple into an I/O vector (array of base pointer/length structures) 490 * 491 * \param[in] buf Input buffer being used to create the iov 492 * \param[in] count Number of elements of the datatype representing the layout 493 * \param[in] type Datatype representing the layout 494 * \param[in] iov_offset Number of contiguous segments to skip 495 * \param[out] iov The I/O vector that is being filled out 496 * \param[in] max_iov_len Maximum number of iov elements that can be added to the vector 497 * \param[out] actual_iov_len Actual number of iov elements that were added to the vector 498 */ 499int yaksa_iov(const char *buf, uintptr_t count, yaksa_type_t type, uintptr_t iov_offset, 500 struct iovec *iov, uintptr_t max_iov_len, uintptr_t * actual_iov_len); 501 502/*! 503 * \brief number of bytes that a flattened representation of the datatype would take 504 * 505 * \param[in] type Datatype to be flattened 506 * \param[out] flattened_type_size Number of bytes the flattened type would take 507 */ 508int yaksa_flatten_size(yaksa_type_t type, uintptr_t * flattened_type_size); 509 510/*! 511 * \brief flattens the datatype into a form that can be sent to other processes in a multiprocess environment 512 * 513 * \param[in] type Datatype to be flattened 514 * \param[out] flattened_type The flattened representation of the datatype 515 */ 516int yaksa_flatten(yaksa_type_t type, void *flattened_type); 517 518/*! 519 * \brief unflattens the datatype into a full datatype 520 * 521 * \param[in] type Datatype generated from the flattened type 522 * \param[out] flattened_type The flattened representation of the datatype 523 */ 524int yaksa_unflatten(yaksa_type_t * type, const void *flattened_type); 525 526/*! @} */ 527 528 529/*! \addtogroup yaksa-version Yaksa versioning information 530 * @{ 531 */ 532 533/******************************************************************************/ 534/* YAKSA VERSION INFORMATION */ 535/******************************************************************************/ 536/* YAKSA_VERSION is the version string. YAKSA_NUMVERSION is the 537 * numeric version that can be used in numeric comparisons. 538 * 539 * YAKSA_VERSION uses the following format: 540 * Version: [MAJ].[MIN].[REV][EXT][EXT_NUMBER] 541 * Example: 1.0.7rc1 has 542 * MAJ = 1 543 * MIN = 0 544 * REV = 7 545 * EXT = rc 546 * EXT_NUMBER = 1 547 * 548 * YAKSA_NUMVERSION will convert EXT to a format number: 549 * ALPHA (a) = 0 550 * BETA (b) = 1 551 * RC (rc) = 2 552 * PATCH (p) = 3 553 * Regular releases are treated as patch 0 554 * 555 * Numeric version will have 1 digit for MAJ, 2 digits for MIN, 2 556 * digits for REV, 1 digit for EXT and 2 digits for EXT_NUMBER. So, 557 * 1.0.7rc1 will have the numeric version 10007201. 558 */ 559/*! \brief Yaksa library version (string format) */ 560#define YAKSA_VERSION "@YAKSA_VERSION@" 561/*! \brief Yaksa library version (numerical format) */ 562#define YAKSA_NUMVERSION @YAKSA_NUMVERSION@ 563 564/*! \brief Yaksa alpha release (used to calculate the numeric version) */ 565#define YAKSA_RELEASE_TYPE_ALPHA 0 566/*! \brief Yaksa beta release (used to calculate the numeric version) */ 567#define YAKSA_RELEASE_TYPE_BETA 1 568/*! \brief Yaksa rc release (used to calculate the numeric version) */ 569#define YAKSA_RELEASE_TYPE_RC 2 570/*! \brief Yaksa GA/patch release (used to calculate the numeric version) */ 571#define YAKSA_RELEASE_TYPE_PATCH 3 572 573/*! \brief Macro to calculate the yaksa numeric version */ 574#define YAKSA_CALC_VERSION(MAJOR, MINOR, REVISION, TYPE, PATCH) \ 575 (((MAJOR) * 10000000) + ((MINOR) * 100000) + ((REVISION) * 1000) + ((TYPE) * 100) + (PATCH)) 576 577/*! @} */ 578 579#if defined(__cplusplus) 580/* } */ 581#endif 582 583#endif /* YAKSA_H_INCLUDED */ 584