This file is indexed.

/usr/include/psm.h is in libpsm-infinipath1-dev 3.3+19.g67c0807.open-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   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
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
/*
 * Copyright (c) 2013. Intel Corporation. All rights reserved.
 * Copyright (c) 2006-2012. QLogic Corporation. All rights reserved.
 * Copyright (c) 2003-2006, PathScale, Inc. All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org 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.
 */

#ifndef PSM_H
#define PSM_H

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif





/* Local endpoint handle (opaque)
 *  
 *
 * Handle returned to the user when a new local endpoint is created.  The
 * handle is a local handle to be used in all communication functions and is
 * not intended to globally identify the opened endpoint in any way.  
 *
 * All open endpoint handles can be globally identified using the endpoint id
 * integral type (psm_epid_t) and all communication must use an endpoint
 * address (psm_epaddr_t) that can be obtained by connecting a local
 * endpoint to one or more endpoint identifiers.
 *
 * @remark The local endpoint handle is opaque to the user.  */
typedef struct psm_ep *psm_ep_t;

/* MQ handle (opaque)
 * 
 *
 * Handle returned to the user when a new Matched queue is created (@ref
 * psm_mq_init).  */
typedef struct psm_mq *psm_mq_t;

#define PSM_VERNO       0x0110
#define PSM_VERNO_MAJOR 0x01
#define PSM_VERNO_MINOR 0x10

enum psm_error {
    
    PSM_OK = 0,
    
    PSM_OK_NO_PROGRESS = 1,
    
    PSM_PARAM_ERR = 3,
    
    PSM_NO_MEMORY = 4,
    
    PSM_INIT_NOT_INIT = 5, 
    
    PSM_INIT_BAD_API_VERSION = 6,
    
    PSM_NO_AFFINITY = 7,
    
    PSM_INTERNAL_ERR = 8,
    
    PSM_SHMEM_SEGMENT_ERR = 9,
    
    PSM_OPT_READONLY = 10,
    
    PSM_TIMEOUT = 11,
    
    PSM_TOO_MANY_ENDPOINTS = 12,

    
    PSM_IS_FINALIZED = 13,

    
    PSM_EP_WAS_CLOSED = 20, 
    
    PSM_EP_NO_DEVICE = 21,
    
    PSM_EP_UNIT_NOT_FOUND = 22,
    
    PSM_EP_DEVICE_FAILURE = 23, 
    
    PSM_EP_CLOSE_TIMEOUT = 24,  
    
    PSM_EP_NO_PORTS_AVAIL = 25, 
    
    PSM_EP_NO_NETWORK = 26,  
    
    PSM_EP_INVALID_UUID_KEY = 27,
    
    PSM_EP_NO_RESOURCES = 28,

    
    PSM_EPID_UNKNOWN = 40,
    
    PSM_EPID_UNREACHABLE = 41,
    
    PSM_EPID_INVALID_NODE = 43,
    
    PSM_EPID_INVALID_MTU =  44,
    
    PSM_EPID_INVALID_UUID_KEY = 45,
    
    PSM_EPID_INVALID_VERSION = 46,
    
    PSM_EPID_INVALID_CONNECT = 47,
    
    PSM_EPID_ALREADY_CONNECTED = 48,
    
    PSM_EPID_NETWORK_ERROR = 49,
    
    PSM_EPID_INVALID_PKEY = 50,
    
    PSM_EPID_PATH_RESOLUTION = 51,

    
    PSM_MQ_NO_COMPLETIONS = 60,
    
    PSM_MQ_TRUNCATION = 61,

    
    PSM_AM_INVALID_REPLY = 70,
    
    PSM_ERROR_LAST = 80
};

/* Backwards header compatibility for a confusing error return name */
#define PSM_MQ_INCOMPLETE PSM_MQ_NO_COMPLETIONS

typedef enum psm_error psm_error_t;

enum psm_component {
  
  PSM_COMPONENT_CORE = 0,
  
  PSM_COMPONENT_MQ = 1,
  
  PSM_COMPONENT_AM = 2,
  
  PSM_COMPONENT_IB = 3
};

typedef enum psm_component psm_component_t;

enum psm_path_res {  
  
  PSM_PATH_RES_NONE = 0,
  
  PSM_PATH_RES_OPP = 1,
  
  PSM_PATH_RES_UMAD = 2
};

typedef enum psm_path_res psm_path_res_t;
  
/* Initialize PSM interface
 *
 * Call to initialize the PSM library for a desired API revision number.
 *
 * [in,out] api_verno_major As input a pointer to an integer that holds
 *                                PSM_VERNO_MAJOR. As output, the pointer
 *                                is updated with the major revision number of
 *                                the loaded library.
 * [in,out] api_verno_minor As intput, a pointer to an integer that holds
 *                                PSM_VERNO_MINOR.  As output, the pointer
 *                                is updated with the minor revision number of
 *                                the loaded library.
 *
 * [pre] The user has not called any other PSM library call except @ref
 *      psm_error_register_handler to register a global error handler.
 *
 * [warning] PSM initialization is a precondition for all functions used in the
 *          PSM library.
 *
 * [returns] PSM_OK The PSM interface could be opened and the desired API
 *                 revision can be provided.
 * [returns] PSM_INIT_BAD_API_VERSION The PSM library cannot compatibility for
 *                                   the desired API version.  
 * 
 * @verbatim
 * // In this example, we want to handle our own errors before doing init,
 * // since we don't want a fatal error if InfiniPath is not found.
 * // Note that psm_error_register_handler (and psm_uuid_generate)
 * // are the only function that can be called before psm_init
 *
 * int try_to_initialize_psm() {
 *     int verno_major = PSM_VERNO_MAJOR;
 *     int verno_minor = PSM_VERNO_MINOR;
 *
 *     int err = psm_error_register_handler(NULL,  // Global handler
 *                                  PSM_ERRHANDLER_NO_HANDLER); // return errors
 *     if (err) {
 *        fprintf(stderr, "Couldn't register global handler: %s\n",
 *		    psm_error_get_string(err));
 *        return -1;
 *     }
 *
 *     err = psm_init(&verno_major, &verno_minor);
 *     if (err || verno_major > PSM_VERNO_MAJOR) {
 *        if (err) 
 *	      fprintf(stderr, "PSM initialization failure: %s\n",
 *	                               psm_error_get_string(err));
 *	  else
 *	      fprintf(stderr, "PSM loaded an unexpected/unsupported "
 *	                      "version (%d.%d)\n", verno_major, verno_minor);
 *	  return -1;
 *     }
 *
 *     // We were able to initialize PSM but will defer all further error
 *     // handling since most of the errors beyond this point will be fatal.
 *     int err = psm_error_register_handler(NULL,  // Global handler
 *                                  PSM_ERRHANDLER_PSM_HANDLER); // 
 *     if (err) {
 *        fprintf(stderr, "Couldn't register global errhandler: %s\n",
 *		    psm_error_get_string(err));
 *        return -1;
 *     }
 *     return 1;
 * }
 * @endverbatim
 */
psm_error_t
psm_init(int *api_verno_major, int *api_verno_minor);

/* Finalize PSM interface
 *
 * Single call to finalize PSM and close all unclosed endpoints 
 *
 * [post] The user guarantees not to make any further PSM calls, including @ref
 * psm_init.
 *
 * [returns] PSM_OK Always returns PSM_OK */
psm_error_t
psm_finalize(void);

/* Error handling opaque token
 *
 * A token is required for users that register their own handlers and wish to
 * defer further error handling to PSM. */
typedef struct psm_error_token	*psm_error_token_t;

/* Error handling function
 *
 * Users can handle errors explicitly instead of relying on PSM's own error
 * handler.  There is one global error handler and error handlers that can be
 * individually set for each opened endpoint.  By default, endpoints will
 * inherit the global handler registered at the time of open. 
 *
 * [in] ep Handle associated to the endpoint over which the error occurred
 *               or NULL if the error is being handled by the global error
 *               handler.
 * [in] error PSM error identifier
 * [in] error_string A descriptive error string of maximum length @ref
 *                         PSM_ERRSTRING_MAXLEN.
 * [in] token Opaque PSM token associated with the particular event that
 *		    generated the error.  The token can be used to extract the
 *		    error string and can be passed to psm_error_defer to
 *		    defer any remaining or unhandled error handling to PSM. 
 *
 * [post] If the error handler returns, the error returned is propagated to the
 *       caller.  */
typedef psm_error_t (*psm_ep_errhandler_t)(psm_ep_t ep, 
					   const psm_error_t error, 
					   const char *error_string,
					   psm_error_token_t token);

/* Obsolete names, only here for backwards compatibility */
#define PSM_ERRHANDLER_DEFAULT	((psm_ep_errhandler_t)-1)
#define PSM_ERRHANDLER_NOP	((psm_ep_errhandler_t)-2)

#define PSM_ERRHANDLER_PSM_HANDLER  ((psm_ep_errhandler_t)-1)
/* PSM error handler as explained in error_handling */

#define PSM_ERRHANDLER_NO_HANDLER   ((psm_ep_errhandler_t)-2)
/* Bypasses the default PSM error handler and returns all errors to the user
 * (this is the default) */

#define PSM_ERRSTRING_MAXLEN	512 /* Maximum error string length. */

/* PSM error handler registration
 *
 * Function to register error handlers on a global basis and on a per-endpoint
 * basis.  PSM_ERRHANDLER_PSM_HANDLER and PSM_ERRHANDLER_NO_HANDLER are special
 * pre-defined handlers to respectively enable use of the default PSM-internal
 * handler or the no-handler that disables registered error handling and
 * returns all errors to the caller (both are documented in error_handling).
 *
 * [in] ep Handle of the endpoint over which the error handler should be
 *               registered.  With ep set to NULL, the behavior of the
 *               global error handler can be controlled.
 * [in] errhandler Handler to register.  Can be a user-specific error
 *                       handling function or PSM_ERRHANDLER_PSM_HANDLER or
 *                       PSM_ERRHANDLER_NO_HANDLER.
 *
 * @remark When ep is set to NULL, this is the only function that can be
 * called before psm_init
 */
psm_error_t
psm_error_register_handler(psm_ep_t ep, const psm_ep_errhandler_t errhandler);

/* PSM deferred error handler 
 *
 * Function to handle fatal PSM errors if no error handler is installed or if
 * the user wishes to defer further error handling to PSM.  Depending on the
 * type of error, PSM may or may not return from the function call.
 *
 * [in] err_token Error token initially passed to error handler
 *
 * [pre] The user is calling into the function because it has decided that PSM
 *      should handle an error case.  
 *
 * [post] The function may or may not return depending on the error
 */
psm_error_t
psm_error_defer(psm_error_token_t err_token);

/* Get generic error string from error
 *
 * Function to return the default error string associated to a PSM error.
 *
 * While a more detailed and precise error string is usually available within
 * error handlers, this function is available to obtain an error string out of
 * an error handler context or when a no-op error handler is registered.
 *
 * [in] error PSM error
 */
const char *
psm_error_get_string(psm_error_t error);

/* Option key/pair structure 
 * 
 * Currently only used in MQ.
 */
struct psm_optkey
{
    uint32_t key;	/* Option key */
    void     *value;	/* Option value */
};



/* Endpoint ID
 *
 * Integral type of size 8 bytes that can be used by the user to globally
 * identify a successfully opened endpoint.  Although the contents of the
 * endpoint id integral type remains opaque to the user, unique network id and
 * InfiniPath port number can be extracted using psm_epid_nid and @ref
 * psm_epid_context.
 */
typedef uint64_t psm_epid_t;

/* Endpoint Address (opaque)
 *
 * Remote endpoint addresses are created when the user binds an endpoint ID
 * to a particular endpoint handle using psm_ep_connect.  A given endpoint
 * address is only guaranteed to be valid over a single endpoint.  
 */
typedef struct psm_epaddr *psm_epaddr_t;

/* PSM Unique UID 
 *
 * PSM type equivalent to the DCE-1 uuid_t, used to uniquely identify an
 * endpoint within a particular job.  Since PSM does not participate in job
 * allocation and management, users are expected to generate a unique ID to
 * associate endpoints to a particular parallel or collective job.
 * [see] psm_uuid_generate
 */
typedef uint8_t psm_uuid_t[16];

/* Get Endpoint identifier's Unique Network ID */
uint64_t
psm_epid_nid(psm_epid_t epid);

/* Get Endpoint identifier's InfiniPath context number */
uint64_t
psm_epid_context(psm_epid_t epid);

/* Get Endpoint identifier's InfiniPath port (deprecated, use
 * psm_epid_context instead) */
uint64_t
psm_epid_port(psm_epid_t epid);

/* List the number of available InfiniPath units
 *
 * Function used to determine the amount of locally available InfiniPath units.
 * For N units, valid unit numbers in psm_ep_open are 0 to N-1.
 *
 * [returns] PSM_OK unless the user has not called psm_init
 */
psm_error_t
psm_ep_num_devunits(uint32_t *num_units);

/* Utility to generate UUIDs for psm_ep_open
 *
 * This function is available as a utility for generating unique job-wide ids.
 * See discussion in psm_ep_open for further information.
 *
 * @remark This function does not require PSM to be initialized.
 */
void
psm_uuid_generate(psm_uuid_t uuid_out);

/* Affinity modes for the affinity member of struct psm_ep_open_opts */
#define PSM_EP_OPEN_AFFINITY_SKIP     0	/* Disable setting affinity */
#define PSM_EP_OPEN_AFFINITY_SET      1	/* Enable setting affinity unless
					  already set */ 
#define PSM_EP_OPEN_AFFINITY_FORCE    2 /* Enable setting affinity regardless
					  of current affinity setting */

/* Default values for some constants */
#define PSM_EP_OPEN_PKEY_DEFAULT    0xffffffffffffffffULL 
				    /* Default protection key */

/* Endpoint Open Options
 *
 * These options are available for opening a PSM endpoint.  Each is
 * individually documented and setting each option to -1 or passing NULL as the
 * options parameter in psm_ep_open instructs PSM to use
 * implementation-defined defaults.
 *
 * Each option is documented in psm_ep_open */
struct psm_ep_open_opts {
    int64_t   timeout;	    /* timeout in nanoseconds to open device */
    int	      unit;	    /* InfiniPath Unit ID to open on */
    int	      affinity;     /* How PSM should set affinity */
    int	      shm_mbytes;   /* Megabytes used for intra-node communication */
    int	      sendbufs_num; /* Preallocated send buffers */
#if PSM_VERNO >= 0x0101
    uint64_t  network_pkey; /* Network Protection Key (v1.01) */
#endif
#if PSM_VERNO >= 0x0107
    int	      port;	      /* IB port to use (1 to N) */
#if PSM_VERNO <= 0x010a
    int	      outvl;	      /* IB VL to use when sending pkts */
#endif
    int	      outsl;	      /* IB SL to use when sending pkts */
#endif
#if PSM_VERNO >= 0x010d
    uint64_t  service_id;     /* IB Service ID to use for endpoint */
    psm_path_res_t path_res_type;  /* Path resolution type */
#endif
#if PSM_VERNO >= 0x010e
    int       senddesc_num;   /* Preallocated send descriptors */
    int       imm_size;       /* Immediate data size for endpoint */
#endif

};

/* InfiniPath endpoint creation
 *
 * Function used to create a new local communication endpoint on an InfiniPath
 * adapter.  The returned endpoint handle is required in all PSM communication
 * operations, as PSM can manage communication over multiple endpoints.  An
 * opened endpoint has no global context until the user connects the endpoint
 * to other global endpoints by way of psm_ep_connect.  All local endpoint
 * handles are globally identified by endpoint IDs (psm_epid_t) which are
 * also returned when an endpoint is opened.  It is assumed that the user can
 * provide an out-of-band mechanism to distribute the endpoint IDs in order to
 * establish connections between endpoints (psm_ep_connect for more
 * information).
 *
 * [in] unique_job_key Endpoint key, to uniquely identify the endpoint in
 *                           a parallel job.  It is up to the user to ensure
 *                           that the key is globally unique over a period long
 *                           enough to prevent duplicate keys over the same set
 *                           of endpoints (see comments below).
 *
 * [in] opts Open options of type psm_ep_open_opts 
 *                 (see psm_ep_open_opts_get_defaults).
 *
 * [out] ep User-supplied storage to return a pointer to the newly
 *                created endpoint.  The returned pointer of type psm_ep_t
 *                is a local handle and cannot be used to globally identify the
 *                endpoint.
 * [out] epid User-supplied storage to return the endpoint ID associated
 *                  to the newly created local endpoint returned in the ep
 *                  handle.  The endpoint ID is an integral type suitable for
 *                  uniquely identifying the local endpoint.
 *
 * PSM does not internally verify the consistency of the uuid, it is up to the
 * user to ensure that the uid is unique enough not to collide with other
 * currently-running jobs.  Users can employ three mechanisms to obtain a uuid.
 *
 * 1. Use the supplied psm_uuid_generate utility
 *
 * 2. Use an OS or library-specific uuid generation utility, that complies with
 *    OSF DCE 1.1, such as uuid_generate on Linux or uuid_create on FreeBSD.
 *    (see http://www.opengroup.org/onlinepubs/009629399/uuid_create.htm)
 *
 * 3. Manually pack a 16-byte string using a utility such as /dev/random or
 *    other source with enough entropy and proper seeding to prevent two nodes
 *    from generating the same uuid_t.
 *
 * The following options are relevent when opening an endpoint:
 *   * timeout establishes the amount of nanoseconds to wait before
 *                  failing to open a port (with -1, defaults to 15 secs).
 *   * unit sets the InfiniPath unit number to use to open a port (with
 *               -1, PSM determines the best unit to open the port).  If @c
 *               IPATH_UNIT is set in the environment, this setting is ignored.
 *   * affinity enables or disables PSM setting processor affinity.  The
 *                   option can be controlled to either disable (@ref
 *                   PSM_EP_OPEN_AFFINITY_SKIP) or enable the affinity setting
 *                   only if it is already unset (@ref
 *                   PSM_EP_OPEN_AFFINITY_SET) or regardless of affinity begin
 *                   set or not (PSM_EP_OPEN_AFFINITY_FORCE).
 *                   If IPATH_NO_CPUAFFINITY is set in the environment, this
 *                   setting is ignored.
 *   * shm_mbytes sets a maximum amount of megabytes that can be allocated
 *		       to each local endpoint ID connected through this
 *		       endpoint (with -1, defaults to 10 MB).
 *   * sendbufs_num sets the number of send buffers that can be
 *                       pre-allocated for communication (with -1, defaults to
 *                       512 buffers of MTU size).
 *   * network_pkey sets the protection key to employ for point-to-point
 *                       PSM communication.  Unless a specific value is used,
 *                       this parameter should be set to
 *                       PSM_EP_OPEN_PKEY_DEFAULT.
 *
 * [warning] Currently, PSM limits the user to calling psm_ep_open only once
 * per process and subsequent calls will fail.  Multiple endpoints per process
 * will be enabled in a future release.
 *
 * @verbatim
 * // In order to open an endpoint and participate in a job, each endpoint has
 * // to be distributed a unique 16-byte UUID key from an out-of-band source.
 * // Presumably this can come from the parallel spawning utility either
 * // indirectly through an implementors own spawning interface or as in this
 * // example, the UUID is set as a string in an environment variable
 * // propagated to all endpoints in the job.
 *
 * int try_to_open_psm_endpoint(psm_ep_t *ep, // output endpoint handle
 *                              psm_epid_t *epid, // output endpoint identifier
 *                              int unit)  // unit of our choice
 * {
 *    psm_ep_open_opts epopts;
 *    psm_uuid_t job_uuid;
 *    char *c;
 *
 *    // Let PSM assign its default values to the endpoint options.
 *    psm_ep_open_opts_get_defaults(&epopts);
 *
 *    // We want a stricter timeout and a specific unit
 *    epopts.timeout = 15*1e9;  // 15 second timeout
 *    epopts.unit = unit;	// We want a specific unit, -1 would let PSM
 *                              // choose the unit for us.
 *    epopts.port = port;	// We want a specific unit, <= 0 would let PSM
 *                              // choose the port for us.
 *    // We've already set affinity, don't let PSM do so if it wants to.
 *    if (epopts.affinity == PSM_EP_OPEN_AFFINITY_SET)
 *       epopts.affinity = PSM_EP_OPEN_AFFINITY_SKIP;
 *
 *    // ENDPOINT_UUID is set to the same value in the environment of all the
 *    // processes that wish to communicate over PSM and was generated by
 *    // the process spawning utility 
 *    c = getenv("ENDPOINT_UUID");
 *    if (c && *c) 
 *       implementor_string_to_16byte_packing(c, job_uuid);
 *    else {
 *       fprintf(stderr, "Can't find UUID for endpoint\n);
 *       return -1;
 *    }
 *
 *    // Assume we don't want to handle errors here.
 *    psm_ep_open(job_uuid, &epopts, ep, epid);
 *    return 1;
 * } 
 * @endverbatim */
psm_error_t
psm_ep_open(const psm_uuid_t unique_job_key, const struct psm_ep_open_opts *opts,
	    psm_ep_t *ep, psm_epid_t *epid);

/* Endpoint open default options.
 *
 * Function used to initialize the set of endpoint options to their default
 * values for use in psm_ep_open.
 *
 * [out] opts Endpoint Open options.
 *
 * [warning] For portable operation, users should always call this function
 * prior to calling psm_ep_open.
 *
 * [return] PSM_OK If result could be updated
 * [return] PSM_INIT_NOT_INIT If psm has not been initialized.
 */
psm_error_t
psm_ep_open_opts_get_defaults(struct psm_ep_open_opts *opts);

/* Endpoint shared memory query
 *
 * Function used to determine if a remote endpoint shares memory with a
 * currently opened local endpiont.
 *
 * [in] ep Endpoint handle
 * [in] epid Endpoint ID
 *
 * [out] result Result is non-zero if the remote endpoint shares memory with the local
 * endpoint ep, or zero otherwise.
 *
 * [return] PSM_OK If result could be updated
 * [return] PSM_EPID_UNKNOWN If the epid is not recognized
 */
psm_error_t
psm_ep_epid_share_memory(psm_ep_t ep, psm_epid_t epid, int *result);

/* Close endpoint
 * [in] ep PSM endpoint handle
 * [in] mode One of PSM_EP_CLOSE_GRACEFUL or PSM_EP_CLOSE_FORCE
 * [in] timeout How long to wait in nanoseconds if mode is
 *			PSM_EP_CLOSE_GRACEFUL, 0 waits forever.  If mode is
 *			PSM_EP_CLOSE_FORCE, this parameter is ignored.
 *
 * The following errors are returned, others are handled by the per-endpoint
 * error handler:
 *
 * [return] PSM_OK  Endpoint was successfully closed without force or
 *                 successfully closed with force within the supplied timeout.
 * [return] PSM_EP_CLOSE_TIMEOUT Endpoint could not be successfully closed
 *                              within timeout.
 */
psm_error_t
psm_ep_close(psm_ep_t ep, int mode, int64_t timeout);

#define PSM_EP_CLOSE_GRACEFUL	0   /* Graceful close mode in psm_ep_close */
#define PSM_EP_CLOSE_FORCE	1   /* Forceful close mode in psm_ep_close */

/* Provide mappings for network id to hostname
 *
 * Since PSM does not assume or rely on the availability of an external
 * networkid-to-hostname mapping service, users can provide one or more of
 * these mappings.  The psm_map_nid_hostname function allows a list of
 * network ids to be associated to hostnames.
 *
 * This function is not mandatory for correct operation but may allow PSM to
 * provide better diagnostics when remote endpoints are unavailable and can
 * otherwise only be identified by their network id.
 *
 * [in] num Number elements in nid and hostnames arrays
 * [in] nids User-provided array of network ids (i.e. InfiniBand LIDs),
 *                 should be obtained by calling psm_epid_nid on each
 *                 epid.
 * [in] hostnames User-provided array of hostnames (array of
 *                      NUL-terimated strings) where each hostname index
 *                      maps to the provided nid hostname.
 *
 * [warning] Duplicate nids may be provided in the input nids array, only
 *          the first corresponding hostname will be remembered.
 *
 * [pre] The user may or may not have already provided a hostname mappings.  
 * [post] The user may free any dynamically allocated memory passed to the
 *       function.
 *
 */
psm_error_t
psm_map_nid_hostname(int num, const uint64_t *nids, const char **hostnames);

/* Connect one or more remote endpoints to a local endpoint
 *
 * Function to non-collectively establish a connection to a set of endpoint IDs
 * and translate endpoint IDs into endpoint addresses.  Establishing a remote
 * connection with a set of remote endpoint IDs does not imply a collective
 * operation and the user is free to connect unequal sets on each process.
 * Similarly, a given endpoint address does not imply that a pairwise
 * communication context exists between the local endpoint and remote endpoint.
 *
 * [in] ep PSM endpoint handle
 *
 * [in] num_of_epid The amount of endpoints to connect to, which
 *			  also establishes the amount of elements contained in
 *			  all of the function's array-based parameters.
 *
 * [in] array_of_epid User-allocated array that contains num_of_epid
 *                          valid endpoint identifiers.  Each endpoint id (or
 *                          epid) has been obtained through an out-of-band
 *                          mechanism and each endpoint must have been opened
 *                          with the same uuid key.
 *
 * [in] array_of_epid_mask User-allocated array that contains num_of_epid
 *			    integers.  This array of masks allows users to
 *			    select which of the epids in array_of_epid
 *			    should be connected.  If the integer at index i is
 *			    zero, psm does not attempt to connect to the epid
 *			    at index i in array_of_epid.  If this parameter
 *			    is NULL, psm will try to connect to each epid.
 *
 * [out] array_of_errors User-allocated array of at least num_of_epid
 *                             elements. If the function does not return
 *                             PSM_OK, this array can be consulted for each
 *                             endpoint not masked off by array_of_epid_mask
 *                             to know why the endpoint could not be connected.
 *                             Endpoints that could not be connected because of
 *                             an unrelated failure will be marked as @ref
 *                             PSM_EPID_UNKNOWN.  If the function returns
 *                             PSM_OK, the errors for all endpoints will also
 *                             contain PSM_OK.
 *
 * [out] array_of_epaddr User-allocated array of at least num_of_epid
 *                             elements of type psm_epaddr_t.  Each
 *                             successfully connected endpoint is updated with
 *                             an endpoint address handle that corresponds to
 *                             the endpoint id at the same index in @c
 *                             array_of_epid.  Handles are only updated if the
 *                             endpoint could be connected and if its error in
 *                             array_of_errors is PSM_OK.
 *
 * [in] timeout Timeout in nanoseconds after which connection attempts will
 *                    be abandoned.  Setting this value to 0 disables timeout
 *                    and waits until all endpoints have been successfully
 *                    connected or until an error is detected.
 *
 * [pre] The user has opened a local endpoint and obtained a list of endpoint
 *      IDs to connect to a given endpoint handle using an out-of-band
 *      mechanism not provided by PSM.
 *
 * [post] If the connect is successful, array_of_epaddr is updated with valid
 *       endpoint addresses.  
 *
 * [post] If unsuccessful, the user can query the return status of each
 *       individual remote endpoint in array_of_errors.
 * 
 * [post] The user can call into psm_ep_connect many times with the same
 *       endpoint ID and the function is guaranteed to return the same output
 *       parameters.
 *
 * [post] PSM does not keep any reference to the arrays passed into the
 *       function and the caller is free to deallocate them.
 *
 * The error value with the highest importance is returned by
 * the function if some portion of the communication failed.  Users should
 * always refer to individual errors in array_of_errors whenever the
 * function cannot return PSM_OK.
 *
 * [returns] PSM_OK  The entire set of endpoint IDs were successfully connected
 *                  and endpoint addresses are available for all endpoint IDs.
 *
 * @verbatim
 * int connect_endpoints(psm_ep_t ep, int numep, const psm_epid_t *array_of_epid,
 *                       psm_epaddr_t **array_of_epaddr_out)
 * {
 *     psm_error_t *errors = (psm_error_t *) 
 *				calloc(numep, sizeof(psm_error_t));
 *     if (errors == NULL)
 *         return -1;
 *
 *     psm_epaddr_t *all_epaddrs = 
 *              (psm_epaddr_t *) calloc(numep, sizeof(psm_epaddr_t));       
 * 
 *     if (all_epaddrs == NULL)
 *         return -1;
 *
 *     psm_ep_connect(ep, numep, array_of_epid, 
 *                    NULL, // We want to connect all epids, no mask needed
 *                    errors,
 *                    all_epaddrs,
 *                    30*e9); // 30 second timeout, <1 ns is forever
 *     *array_of_epaddr_out = all_epaddrs;
 *     free(errors);
 *     return 1;
 * }
 * @endverbatim */
psm_error_t
psm_ep_connect(psm_ep_t ep, int num_of_epid, const psm_epid_t *array_of_epid,
	       const int *array_of_epid_mask, psm_error_t *array_of_errors, 
	       psm_epaddr_t *array_of_epaddr, int64_t timeout);

/* Ensure endpoint communication progress 
 *
 * Function to ensure progress for all PSM components instantiated on an
 * endpoint (currently, this only includes the MQ component).  The function
 * never blocks and is typically required in two cases:
 *
 * * Allowing all PSM components instantiated over a given endpoint to make
 *     communication progress. Refer to mq_progress for a detailed
 *     discussion on MQ-level progress issues.
 *
 * * Cases where users write their own synchronization primitives that
 *     depend on remote communication (such as spinning on a memory location
 *     which's new value depends on ongoing communication).
 *
 * The poll function doesn't block, but the user can rely on the @ref
 * PSM_OK_NO_PROGRESS return value to control polling behaviour in terms of
 * frequency (poll until an event happens) or execution environment (poll for a
 * while but yield to other threads of CPUs are oversubscribed).
 *
 * [returns] PSM_OK	       Some communication events were progressed
 * [returns] PSM_OK_NO_PROGRESS Polling did not yield any communication progress
 *
 */
psm_error_t
psm_poll(psm_ep_t ep);

/* Set a user-determined ep address label.
 *
 * [in] epaddr Endpoint address, obtained from psm_ep_connect
 * [in] epaddr_label_string User-allocated string to print when
 *                   identifying endpoint in error handling or other verbose
 *                   printing.  The NULL-terminated string must be allocated by
 *                   the user since PSM only keeps a pointer to the label.  If
 *                   users do not explicitly set a label for each endpoint,
 *                   endpoints will identify themselves as hostname:port.
 */
void
psm_epaddr_setlabel(psm_epaddr_t epaddr, const char *epaddr_label_string);

/* Set a user-determined ep address context.
 *
 * [in] epaddr Endpoint address, obtained from psm_ep_connect
 * [in] ctxt   Opaque user defined state to associate with an endpoint
 *                   address. This state can be retrieved via 
 *                   psm_epaddr_getctxt.
 */
void 
psm_epaddr_setctxt(psm_epaddr_t epaddr, void *ctxt);

/* Get the user-determined ep address context. Users can associate an
 *  opaque context with each endpoint via psm_epaddr_setctxt.
 *
 * [in] epaddr Endpoint address, obtained from psm_ep_connect.
 */  
void *
psm_epaddr_getctxt(psm_epaddr_t epaddr);

/* Below are all component specific options. The component object for each of
 * the options is also specified. 
 */
  
/* PSM_COMPONENT_CORE options */
/* PSM debug level */
#define PSM_CORE_OPT_DEBUG     0x101
  /* [uint32_t ] Set/Get the PSM debug level. This option can be set
   * before initializing the PSM library.
   *
   * component object: (null)
   * option value: PSM Debug mask to set or currently active debug level.
   */
  
/* PSM endpoint address context */  
#define PSM_CORE_OPT_EP_CTXT   0x102
  /* [uint32_t ] Set/Get the context associated with a PSM endpoint
   * address (psm_epaddr_t).
   *
   * component object: PSM endpoint (psm_epaddr_t) address.
   * option value: Context associated with PSM endpoint address.
   */

/* PSM_COMPONENT_IB options */
/* Default service level to use to communicate with remote endpoints */
#define PSM_IB_OPT_DF_SL 0x201
  /* [uint32_t ] Default Infiniband SL to use for all remote communication.
   * If unset defaults to Service Level 0. 
   *
   * component object: Opened PSM endpoint id (psm_ep_t).
   * option value: Default IB SL to use for endpoint. (0 <= SL < 15)
   */

/* Set IB service level to use for communication to an endpoint */
#define PSM_IB_OPT_EP_SL 0x202
  /* [uint32_t ] Infiniband SL to use for communication to specified
   * remote endpoint.
   * 
   * component object: PSM endpoint (@ ref psm_epaddr_t) address.
   * option value: SL used to communicate with remote endpoint. (0 <= SL < 15)
   */

/* PSM_COMPONENT_MQ options (deprecates psm_mq_set|getopt) */
/* MQ options that can be set in psm_mq_init and psm_{set,get}_opt */
#define PSM_MQ_OPT_RNDV_IB_SZ       0x301
#define PSM_MQ_RNDV_IPATH_SZ	    PSM_MQ_OPT_RNDV_IB_SZ 
  /* [uint32_t ] Size at which to start enabling rendezvous
   * messaging for InfiniPath messages (if unset, defaults to values
   * between 56000 and 72000 depending on the system configuration) 
   *
   * component object: PSM Matched Queue (psm_mq_t).
   * option value: Size at which to switch to rendezvous protocol.
   */
  
#define PSM_MQ_OPT_RNDV_SHM_SZ      0x302
#define PSM_MQ_RNDV_SHM_SZ	    PSM_MQ_OPT_RNDV_SHM_SZ
  /* [uint32_t ] Size at which to start enabling
   * rendezvous messaging for shared memory (intra-node) messages (If
   * unset, defaults to 64000 bytes). 
   *
   * component object: PSM Matched Queue (psm_mq_t).
   * option value: Size at which to switch to rendezvous protocol.
   */
  
#define PSM_MQ_OPT_SYSBUF_MYBYTES   0x303
#define PSM_MQ_MAX_SYSBUF_MBYTES    PSM_MQ_OPT_SYSBUF_MYBYTES
  /* [uint32_t ] Maximum amount of bytes to allocate for unexpected
   * messages.
   *
   * component object: PSM Matched Queue (psm_mq_t).
   * option value: Maximum amount of bytes to allocate for unexpected messages.
   * Mesages that would cause memory allocation to exceed this amount will be
   * dropped.
   */


/* PSM_COMPONENT_AM options */
#define PSM_AM_OPT_FRAG_SZ          0x401
  
  
/* Set an option for a PSM component
 *
 * Function to set the value of a PSM component option
 *
 * [in] component Type of PSM component for which to set the option
 * [in] component_obj Opaque component specify object to apply the set
 *                          operation on. These are passed uninterpreted to the
 *                          appropriate component for interpretation.
 * [in] optname Name of component option to set. These are component
 *                    specific and passed uninterpreted to the appropriate
 *                    component for interpretation.
 * [in] optval Pointer to storage that contains the value to be updated
 *                   for the supplied option.  It is up to the user to
 *                   ensure that the pointer points to a memory location with a
 *                   correct size and format.
 * [in] optlen Size of the memory region pointed to by optval.
 *
 * [returns] PSM_OK if option could be set.
 * [returns] PSM_PARAM_ERR if the component or optname are not valid.
 * [returns] PSM_OPT_READONLY if the option to be set is a read-only option.
 *                           
 */
psm_error_t
psm_setopt(psm_component_t component, const void *component_obj,
	   int optname, const void *optval, uint64_t optlen);

/* Get an option for a PSM component
 *
 * Function to get the value of a PSM component option
 *
 * [in] component Type of PSM component for which to get the option
 * [in] component_obj Opaque component specify object to apply the get
 *                          operation on. These are passed uninterpreted to the
 *                          appropriate component for interpretation.
 * [in] optname Name of component option to get. These are component
 *                    specific and passed uninterpreted to the appropriate
 *                    component for interpretation.
 * [out] optval Pointer to storage that contains the value to be updated
 *                    for the supplied option.  It is up to the user to
 *                    ensure that the pointer points to a valid memory region.
 * [in,out] optlen This is a value result parameter initially containing 
 *                      the size of the memory region pointed to by optval and 
 *                      modified to return the actual size of optval.
 *
 * [returns] PSM_OK if option value could be retrieved successfully.
 * [returns] PSM_PARAM_ERR if the component or optname are not valid.
 * [returns] PSM_NO_MEMORY if the memory region optval is of insufficient size.
 *                         optlen contains the required memory region size for
 *                         optname value.
 *
 */
psm_error_t
psm_getopt(psm_component_t component, const void *component_obj,
	   int optname, void *optval, uint64_t *optlen);

/* Datatype for end-point information */
typedef struct psm_epinfo {
    psm_ep_t ep;	/* The ep for this end-point*/
    psm_epid_t epid;	/* The epid for this end-point */
    psm_uuid_t uuid;	/* The UUID for this end-point */
    char uuid_str[64];	/* String representation of the UUID for this end-point */
} psm_epinfo_t;

/* Datatype for end-point connection */
typedef struct psm_epconn {
    psm_epaddr_t addr;	/* The epaddr for this connection */
    psm_ep_t ep;	/* The ep for this connection */
    psm_mq_t mq;	/* The mq for this connection */
} psm_epconn_t;

/* Query PSM for end-point information.
 *
 * Function to query PSM for end-point information. This allows retrieval of end-point
 * information in cases where the caller does not have access to the results of psm_ep_open().
 * In single-rail mode PSM will use a single end-point. In multi-rail mode, PSM will use an 
 * end-point per rail.
 *
 * [in,out] num_of_epinfo On input, sizes the available number of entries in array_of_epinfo.
 *                             On output, specifies the returned number of entries in array_of_epinfo.
 * [out] array_of_epinfo Returns end-point information structures.
 *
 * [pre] PSM is initialized and the end-point has been opened.
 *
 * [returns] PSM_OK indicates success.
 * [returns] PSM_PARAM_ERR if input num_if_epinfo is less than or equal to zero.
 * [returns] PSM_EP_WAS_CLOSED if PSM end-point is closed or does not exist.
 */
psm_error_t 
psm_ep_query (int *num_of_epinfo, psm_epinfo_t *array_of_epinfo);

/* Query PSM for end-point connections.
 *
 * Function to query PSM for end-point connections. This allows retrieval of end-point
 * connnections in cases where the caller does not have access to the results of psm_ep_connect().
 * The epid values can be found using psm_ep_query() so that each PSM process can determine
 * its own epid. These values can then be distributed across the PSM process so that each PSM
 * process knows the epid for all other PSM processes.
 *
 * [in] epid The epid of a PSM process.
 * [out] epconn The connection information for that PSM process.
 *
 * [pre] PSM is initialized and the end-point has been connected to this epid.
 *
 * [returns] PSM_OK indicates success.
 * [returns] PSM_EP_WAS_CLOSED if PSM end-point is closed or does not exist.
 * [returns] PSM_EPID_UNKNOWN if the epid value is not known to PSM.
 */
psm_error_t 
psm_ep_epid_lookup (psm_epid_t epid, psm_epconn_t *epconn);
  

#ifdef __cplusplus
}				/* extern "C" */
#endif
#endif