text:
/*
  Copyright [2017-2021] [IBM Corporation]
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
  http://www.apache.org/licenses/LICENSE-2.0
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

#ifndef __API_MCAS_ITF__
#define __API_MCAS_ITF__

#include <api/components.h>
#include <api/kvindex_itf.h>
#include <api/kvstore_itf.h>
#include <boost/optional.hpp>
#include <common/byte_span.h>
#include <common/pointer_cast.h>
#include <common/string_view.h>
#include <gsl/span>

#include <array>
#include <cstdint> /* uint16_t */
#include <memory>

#define DECLARE_OPAQUE_TYPE(NAME)               \
  struct Opaque_##NAME {                        \
    virtual ~Opaque_##NAME() {}                 \
  }

namespace component
{
/**
 * mcas client interface (this will include both KV and AS capabilities)
 */

class IMCAS : public component::IBase,
              public KVStore
{
public:
  // clang-format off
  DECLARE_INTERFACE_UUID(0x33af1b99,0xbc51,0x49ff,0xa27b,0xd4,0xe8,0x19,0x03,0xbb,0x02);
  // clang-format on

public:
  DECLARE_OPAQUE_TYPE(async_handle);

  using async_handle_t  = Opaque_async_handle*;
  using pool_t          = component::KVStore::pool_t;
  using key_t           = KVStore::key_t;
  using Attribute       = KVStore::Attribute;
  using Addr            = KVStore::Addr;

  static constexpr async_handle_t  ASYNC_HANDLE_INIT  = nullptr;

  enum {
        FLAGS_NONE        = KVStore::FLAGS_NONE,
        FLAGS_READ_ONLY   = KVStore::FLAGS_READ_ONLY,
        FLAGS_SET_SIZE    = KVStore::FLAGS_SET_SIZE,
        FLAGS_CREATE_ONLY = KVStore::FLAGS_CREATE_ONLY,
        FLAGS_DONT_STOMP  = KVStore::FLAGS_DONT_STOMP,
        FLAGS_NO_RESIZE   = KVStore::FLAGS_NO_RESIZE,
        FLAGS_MAX_VALUE   = KVStore::FLAGS_MAX_VALUE,
  };

  /* per-shard statistics */
  struct Shard_stats {
    uint64_t op_request_count;
    uint64_t op_put_count;
    uint64_t op_get_count;
    uint64_t op_put_direct_count;
    uint64_t op_get_direct_count;
    uint64_t op_get_twostage_count;
    uint64_t op_ado_count;
    uint64_t op_erase_count;
    uint64_t op_get_direct_offset_count;
    uint64_t op_failed_request_count;
    uint64_t last_op_count_snapshot;
    uint16_t client_count;

  public:
    Shard_stats()
      : op_request_count(0)
      , op_put_count(0), op_get_count(0), op_put_direct_count(0), op_get_direct_count(0), op_get_twostage_count(0)
      , op_ado_count(0), op_erase_count(0), op_get_direct_offset_count(0)
      , op_failed_request_count(0), last_op_count_snapshot(0), client_count(0)
    {
    }
  } __attribute__((packed));

  using ado_flags_t = uint32_t;

  static constexpr ado_flags_t ADO_FLAG_NONE = 0;
  /*< operation is asynchronous */
  static constexpr ado_flags_t ADO_FLAG_ASYNC = (1 << 0);
  /*< create KV pair if needed */
  static constexpr ado_flags_t ADO_FLAG_CREATE_ON_DEMAND = (1 << 1);
  /*< create only - allocate key,value but don't call ADO */
  static constexpr ado_flags_t ADO_FLAG_CREATE_ONLY = (1 << 2);
  /*< do not overwrite value if it already exists */
  static constexpr ado_flags_t ADO_FLAG_NO_OVERWRITE = (1 << 3);
  /*< create value but do not attach to key, unless key does not exist */
  static constexpr ado_flags_t ADO_FLAG_DETACHED = (1 << 4);
  /*< only take read lock */
  static constexpr ado_flags_t ADO_FLAG_READ_ONLY = (1 << 5);
  /*< zero any newly allocated value memory */
  static constexpr ado_flags_t ADO_FLAG_ZERO_NEW_VALUE = (1 << 6);
  /*< internal use only: on return provide IO response */
  static constexpr ado_flags_t ADO_FLAG_INTERNAL_IO_RESPONSE = (1 << 7);
  /*< internal use only: on return provide IO response with value buffer */
  static constexpr ado_flags_t ADO_FLAG_INTERNAL_IO_RESPONSE_VALUE = (1 << 8);

public:
  /**
   * Determine thread safety of the component
   *
   *
   * @return THREAD_MODEL_XXXX
   */
  virtual int thread_safety() const = 0;

  /**
   * If the ADO is configured for the shard then the ADO process is
   * instantiated "attached" to the pool.
   *
   * The "base" parameter is unused.
   */
  using KVStore::create_pool;
  using KVStore::open_pool;

  using KVStore::delete_pool;

  /**
   * Close and delete an existing pool from a pool handle. Only one
   * reference count should exist. Any ADO plugin is notified before
   * the pool is deleted.
   *
   * @param pool Pool handle
   *
   * @return S_OK or E_BUSY if reference count > 1
   */
  virtual status_t delete_pool(const pool_t pool) = 0;

  /**
   * Configure a pool
   *
   * @param setting Configuration request (e.g., AddIndex::VolatileTree)

   *
   * @return S_OK on success
   */
  virtual status_t configure_pool(const pool_t pool, const std::string& setting) = 0;

  using KVStore::put;

  virtual status_t put(const pool_t pool,
                       const std::string&  key,
                       const std::string&  value,
                       const unsigned int  flags = FLAGS_NONE)
  {
    /* this does not store any null terminator */
    return put(pool, key, value.data(), value.length(), flags);
  }

  /*
   * Asynchronous put operation.  Use check_async_completion to check for
   * completion. This operation is not normally used, simple put is fast.
   *
   * @param pool Pool handle
   * @param key Object key
   * @param value Value

   * @param value_len Value length in bytes
   * @param out_handle Async work handle
   * @param flags Optional flags
   *
   * @return S_OK or other error code
   */
  virtual status_t async_put(const IMCAS::pool_t pool,
                             const std::string&  key,
                             const void*         value,
                             const size_t        value_len,
                             async_handle_t&     out_handle,
                             const unsigned int  flags = IMCAS::FLAGS_NONE) = 0;

  virtual status_t async_put(const IMCAS::pool_t pool,
                             const std::string&  key,
                             const std::string&  value,
                             async_handle_t&     out_handle,
                             const unsigned int  flags = IMCAS::FLAGS_NONE)
  {
    (void)out_handle; // unused
    return async_put(pool, key, value.data(), value.length(), out_handle, flags);
  }

  /**
   * Zero-copy only if value size > ~2MiB or FORCE_DIRECT=1 is set.
   */
  using KVStore::put_direct;

  /**
   * Asynchronous put_direct operation.  Use check_async_completion to check for
   * completion.
   *
   * @param pool Pool handle
   * @param key Object key
   * @param value Value
   * @param value_len Value length in bytes
   * @param handle Memory registration handle
   * @param out_handle Async handle
   * @param flags Optional flags
   *
   * @return S_OK or other error code
   */
  virtual status_t async_put_direct(const IMCAS::pool_t   pool,
                                    const std::string&    key,
                                    const void*           value,
                                    const size_t          value_len,
                                    async_handle_t&       out_handle,
                                    const memory_handle_t handle = IMCAS::MEMORY_HANDLE_NONE,
                                    const unsigned int    flags  = IMCAS::FLAGS_NONE)
  {
    return
      async_put_direct(
                       pool
                       , key
                       , std::array<common::const_byte_span,1>{common::make_const_byte_span(value, value_len)}
                       , out_handle, std::array<memory_handle_t,1>{handle}
                       , flags
                       );
  }

  /**
   * Asynchronous put_direct operation.  Use check_async_completion to check for
   * completion.
   *
   * @param pool Pool handle
   * @param key Object key
   * @param values list of value sources
   * @param out_handle Async handle
   * @param handle List of memory registration handle
   * @param flags Optional flags
   *
   * @return S_OK or other error code
   */
  virtual status_t async_put_direct(const IMCAS::pool_t   pool,
                                    const std::string&    key,
                                    gsl::span<const common::const_byte_span> value,
                                    async_handle_t&       out_handle,
                                    gsl::span<const memory_handle_t> handles = gsl::span<const memory_handle_t>(),
                                    const unsigned int    flags  = IMCAS::FLAGS_NONE) = 0;

  using KVStore::get;

  virtual status_t get(const pool_t pool,
                       const std::string& key,
                       std::string& out_value)
  {
    void*  val      = nullptr;
    size_t val_size = 0;
    auto   s        = this->get(pool, key, val, val_size);

    /* copy result */
    if (s == S_OK) {
      out_value.assign(static_cast<char*>(val), val_size);
      this->free_memory(val);
    }
    return s;
  }

  /**
   * Asynchronously read an object value directly into client-provided memory.
   *
   * @param pool Pool handle
   * @param key Object key
   * @param out_value Client provided buffer for value
   * @param out_value_len [in] size of value memory in bytes [out] size of value
   * @param out_handle Async work handle
   * @param handle Memory registration handle
   *
   * @return S_OK, S_MORE if only a portion of value is read, E_BAD_ALIGNMENT on
   * invalid alignment, or other error code
   */
  virtual status_t async_get_direct(const IMCAS::pool_t          pool,
                                    const std::string&           key,
                                    void*                        out_value,
                                    size_t&                      out_value_len,
                                    async_handle_t&              out_handle,
                                    const IMCAS::memory_handle_t handle = IMCAS::MEMORY_HANDLE_NONE) = 0;

  /**
   * Read memory directly into client-provided memory.
   *
   * @param pool Pool handle
   * @param offset offset within ithe concatenation of the pool's memory regions
   * @param size requested size (becomes available size)
   * @param out_buffer Client provided buffer for value
   * @param out_handle Async work handle
   * @param handle Memory registration handle
   *
   * @return S_OK, or error code
   */
  virtual status_t async_get_direct_offset(const IMCAS::pool_t pool,
                                           const offset_t offset,
                                           size_t &size,
                                           void* out_buffer,
                                           async_handle_t& out_handle,
                                           const IMCAS::memory_handle_t handle = IMCAS::MEMORY_HANDLE_NONE) = 0;

  virtual status_t get_direct_offset(const IMCAS::pool_t pool,
                                     const offset_t offset,
                                     size_t &size,
                                     void* out_buffer,
                                     const IMCAS::memory_handle_t handle = IMCAS::MEMORY_HANDLE_NONE) = 0;

  /**
   * Write memory directly into client-provided memory.
   *
   * @param pool Pool handle
   * @param offset offset within ithe concatenation of the pool's memory regions
   * @param size offered size (becomes available size)
   * @param buffer Client provided value
   * @param out_handle Async work handle
   * @param handle Memory registration handle
   *
   * @return S_OK, or error code
   */
  virtual status_t async_put_direct_offset(const IMCAS::pool_t pool,
                                           const offset_t offset,
                                           size_t &size,
                                           const void *const buffer,
                                           async_handle_t& out_handle,
                                           const IMCAS::memory_handle_t handle = IMCAS::MEMORY_HANDLE_NONE) = 0;

  virtual status_t put_direct_offset(const IMCAS::pool_t pool,
                                     const offset_t offset,
                                     size_t &size,
                                     const void *const buffer,
                                     const IMCAS::memory_handle_t handle = IMCAS::MEMORY_HANDLE_NONE) = 0;

  /**
   * Check for completion from asynchronous invocation
   *
   * @param handle Asynchronous work handle.
   *
   * @return S_OK or E_BUSY if not yet complete
   */
  virtual status_t check_async_completion(async_handle_t& handle) = 0;

  /**
   * Perform key search based on regex or prefix
   *
   * @param pool Pool handle
   * @param key_expression Regular expression or prefix (e.g. "prefix:carKey")
   * @param offset Offset from which to search
   * @param out_matched_offset Out offset of match
   * @param out_keys Out vector of matching keys
   *
   * @return S_OK on success
   */
  virtual status_t find(const IMCAS::pool_t pool,
                        const std::string&  key_expression,
                        const offset_t      offset,
                        offset_t&           out_matched_offset,
                        std::string&        out_matched_key) = 0;

  /**
   * Erase an object asynchronously
   *
   * @param pool Pool handle
   * @param key Object key
   * @param out_handle Async work handle
   *
   * @return S_OK or error code
   */
  virtual status_t async_erase(const IMCAS::pool_t pool, const std::string& key, async_handle_t& out_handle) = 0;

  /**
   * Retrieve shard statistics
   *
   * @param out_stats
   *
   * @return S_OK on success
   */
  virtual status_t get_statistics(Shard_stats& out_stats) = 0;

  /**
   * ADO_response data structure manages response data sent back from the ADO
   * invocations.  The free function is so we can eventually support zero-copy.
   * The layer id identifies which ADO plugin the response came from.
   */
  class ADO_response {

  private:

#pragma GCC diagnostic push /* pointer members are considered inefficient */
#pragma GCC diagnostic ignored "-Weffc++"

    class Data_reference {
    public:
      Data_reference(void * data) : _data(data) { assert(data); }
      Data_reference() = delete;
      virtual ~Data_reference() { assert(_data); ::free(_data); }
      void * _data;
    };

#pragma GCC diagnostic pop

  public:
    ADO_response() = delete;

    ADO_response(void* data, size_t data_len, uint32_t layer_id)
      : _ref(std::make_shared<Data_reference>(data)),
        _data_len(data_len),
        _layer_id(layer_id) {}

    ADO_response(ADO_response&& src) noexcept
      : _ref(src.datasp()),
        _data_len(src.data_len()),
        _layer_id(src.layer_id()) {}

    inline std::string str() const { return std::string(data(), data_len()); }
    inline const char* data() const { return static_cast<const char*>(_ref->_data); }
    inline size_t data_len() const { return _data_len; }
    inline uint32_t layer_id() const { return _layer_id; }
    inline std::shared_ptr<Data_reference>& datasp() { return _ref; }

    template <typename T>
    inline T* cast_data() const  {  return static_cast<T*>(_ref->_data);   }

  private:
    std::shared_ptr<Data_reference> _ref; /* smart pointer */
    size_t                          _data_len;
    uint32_t                        _layer_id; /* optional layer identifier */
  };

  /**
   * Used to invoke an operation on an active data object
   *
   * Roughly, the shard locates a data value by key and calls ADO (with accessors to both the key and data).
   *   Several variations:
   *       1) Skip the "locate data" operation (could have been directed by a null
   *          key address in the basic_string_view form, or by a flag, but is
   *          instead indicated by a zero-length key)
   *       2) Skip the ADO call (directed by ADO_FLAG_CREATE_ONLY)
   *       3) Create uninitialized data of size value_size if the key was not found
   *          (directed by ADO_FLAG_CREATE_ON_DEMAND)
   *       4) Create uninitialized data of size value_size if the key was not found(?)
   *          not associated with the key and maybe also create a "root value" which
   *          which is attached to the key (directed by ADO_FLAG_DETACHED)
   *
   * @param pool Pool handle
   * @param key Key. Note, if key is empty, the work request is key-less.
   * @param request Request data
   * @param request_len Length of request in bytes
   * @param flags Flags for invocation (see ADO_FLAG_CREATE_ONLY, ADO_FLAG_READ_ONLY)
   * @param out_response Responses from invocation
   * @param value_size Optional parameter to define value size to create for
   * on-demand
   *
   * @return S_OK on success
   */
  virtual status_t invoke_ado(const IMCAS::pool_t           pool,
                              const basic_string_view<byte> key,
                              const basic_string_view<byte> request,
                              const ado_flags_t             flags,
                              std::vector<ADO_response>&    out_response,
                              const size_t                  value_size = 0) = 0;

  virtual status_t invoke_ado(const IMCAS::pool_t        pool,
                              const std::string&         key,
                              const void*                request,
                              const size_t               request_len,
                              const ado_flags_t          flags,
                              std::vector<ADO_response>& out_response,
                              const size_t               value_size = 0)
  {
    return
      invoke_ado(pool,
                 basic_string_view<byte>(common::pointer_cast<const byte>(key.data()), key.size()),
                 basic_string_view<byte>(static_cast<const byte *>(request), request_len),
                 flags, out_response, value_size);
  }

  inline status_t invoke_ado(const IMCAS::pool_t        pool,
                             const std::string&         key,
                             const std::string&         request,
                             const ado_flags_t          flags,
                             std::vector<ADO_response>& out_response,
                             const size_t               value_size = 0)
  {
    return
      invoke_ado(pool, key, request.data(), request.length(), flags, out_response, value_size);
  }

  /**
   * Used to asynchronously invoke an operation on an ADO
   *
   * Roughly, the shard locates a data value by key and calls ADO (with accessors to both the key and data).
   *
   * @param pool Pool handle
   * @param key Key. Note, if key is empty, the work request is key-less.
   * @param request Request data
   * @param request_len Length of request in bytes
   * @param flags Flags for invocation (see ADO_FLAG_XXX)
   * @param out_response Response passed back from ADO invocation
   * @param out_async_handle Handle to task for later result collection
   * @param value_size Optional parameter to define value size to create for on-demand
   *
   * @return S_OK on success
   */
  virtual status_t async_invoke_ado(const IMCAS::pool_t           pool,
                                    const basic_string_view<byte> key,
                                    const basic_string_view<byte> request,
                                    const ado_flags_t             flags,
                                    std::vector<ADO_response>&    out_response,
                                    async_handle_t&               out_async_handle,
                                    const size_t                  value_size = 0) = 0;

  inline status_t async_invoke_ado(const IMCAS::pool_t        pool,
                                   const std::string&         key,
                                   const std::string&         request,
                                   const ado_flags_t          flags,
                                   std::vector<ADO_response>& out_response,
                                   async_handle_t&            out_async_handle,
                                   const size_t               value_size = 0)
  {
    return
      async_invoke_ado(pool,
                       basic_string_view<byte>(common::pointer_cast<const byte>(key.data()), key.size()),
                       basic_string_view<byte>(common::pointer_cast<const byte>(request.data()), request.length()),
                       flags, out_response, out_async_handle, value_size);
  }

  inline status_t async_invoke_ado(const IMCAS::pool_t        pool,
                                   const std::string&         key,
                                   const void*                request,
                                   const size_t               request_len,
                                   const ado_flags_t          flags,
                                   std::vector<ADO_response>& out_response,
                                   async_handle_t&            out_async_handle,
                                   const size_t               value_size = 0)
  {
    return
      async_invoke_ado(pool,
                       basic_string_view<byte>(common::pointer_cast<const byte>(key.data()), key.size()),
                       basic_string_view<byte>(static_cast<const byte *>(request), request_len),
                       flags, out_response, out_async_handle, value_size);
  }

  /**
   * Used to invoke a combined put + ADO operation on an active data object.
   *
   * Roughly, the shard writes a data value by key and calls ADO (with accessors to both the key and data).
   *
   * @param pool Pool handle
   * @param key Key
   * @param request Request data
   * @param request_len Length of request data in bytes
   * @param value Value data
   * @param value_len Length of value data in bytes
   * @param root_len Length to allocate for root value (with ADO_FLAG_DETACHED)
   * @param flags Flags for invocation (ADO_FLAG_NO_OVERWRITE, ADO_FLAG_DETACHED)
   * @param out_response Response passed back from ADO invocation
   *
   * @return S_OK on success
   */
  virtual status_t invoke_put_ado(const IMCAS::pool_t           pool,
                                  const basic_string_view<byte> key,
                                  const basic_string_view<byte> request,
                                  const basic_string_view<byte> value,
                                  const size_t                  root_len,
                                  const ado_flags_t             flags,
                                  std::vector<ADO_response>&    out_response) = 0;

  virtual status_t invoke_put_ado(const IMCAS::pool_t        pool,
                                  const std::string&         key,
                                  const void*                request,
                                  const size_t               request_len,
                                  const void*                value,
                                  const size_t               value_len,
                                  const size_t               root_len,
                                  const ado_flags_t          flags,
                                  std::vector<ADO_response>& out_response)
  {
    return
      invoke_put_ado(pool,
                     basic_string_view<byte>(common::pointer_cast<const byte>(key.data()), key.size()),
                     basic_string_view<byte>(static_cast<const byte *>(request), request_len),
                     basic_string_view<byte>(static_cast<const byte *>(value), value_len),
                     root_len, flags, out_response);
  }

  inline status_t invoke_put_ado(const IMCAS::pool_t        pool,
                                 const std::string&         key,
                                 const std::string&         request,
                                 const std::string&         value,
                                 const size_t               root_len,
                                 const ado_flags_t          flags,
                                 std::vector<ADO_response>& out_response)
  {
    return invoke_put_ado(pool,
                          key,
                          request.data(),
                          request.length(),
                          value.data(),
                          value.length(),
                          root_len,
                          flags,
                          out_response);
  }

  /**
   * Used to asynchronously invoke a combined put + ADO operation on an active data object.
   *
   * Roughly, the shard writes a data value by key and calls ADO (with accessors to both the key and data).
   *
   * @param pool Pool handle
   * @param key Key
   * @param request Request data
   * @param request_len Length of request data in bytes
   * @param value Value data
   * @param value_len Length of value data in bytes
   * @param root_len Length to allocate for root value (with ADO_FLAG_DETACHED)
   * @param flags Flags for invocation (ADO_FLAG_NO_OVERWRITE, ADO_FLAG_DETACHED)
   * @param out_response Responses from ADO invocation
   * @param out_async_handle Handle to task for later result collection
   *
   * @return S_OK on success
   */
  virtual status_t async_invoke_put_ado(const IMCAS::pool_t           pool,
                                        const basic_string_view<byte> key,
                                        const basic_string_view<byte> request,
                                        const basic_string_view<byte> value,
                                        const size_t                  root_len,
                                        const ado_flags_t             flags,
                                        std::vector<ADO_response>&    out_response,
                                        async_handle_t&               out_async_handle) = 0;

  virtual status_t async_invoke_put_ado(const IMCAS::pool_t        pool,
                                        const std::string&         key,
                                        const void*                request,
                                        const size_t               request_len,
                                        const void*                value,
                                        const size_t               value_len,
                                        const size_t               root_len,
                                        const ado_flags_t          flags,
                                        std::vector<ADO_response>& out_response,
                                        async_handle_t&            out_async_handle)
  {
    return
      async_invoke_put_ado(pool,
                           basic_string_view<byte>(common::pointer_cast<const byte>(key.data()), key.size()),
                           basic_string_view<byte>(static_cast<const byte *>(request), request_len),
                           basic_string_view<byte>(static_cast<const byte *>(value), value_len),
                           root_len, flags, out_response, out_async_handle);
  }

  inline status_t async_invoke_put_ado(const IMCAS::pool_t        pool,
                                       const std::string&         key,
                                       const std::string&         request,
                                       const std::string&         value,
                                       const size_t               root_len,
                                       const ado_flags_t          flags,
                                       std::vector<ADO_response>& out_response,
                                       async_handle_t&            out_async_handle)
  {
    return async_invoke_put_ado(pool,
                                key,
                                request.data(),
                                request.length(),
                                value.data(),
                                value.length(),
                                root_len,
                                flags,
                                out_response,
                                out_async_handle);
  }

  /**
   * Debug routine
   *
   * @param pool Pool handle
   * @param cmd Debug command
   * @param arg Parameter for debug operation
   */
  virtual void debug(const IMCAS::pool_t pool, const unsigned cmd, const uint64_t arg) = 0;
};

class IMCAS_factory : public IKVStore_factory {
  using string_view = common::string_view;
public:
  // clang-format off
  DECLARE_INTERFACE_UUID(0xfacf1b99,0xbc51,0x49ff,0xa27b,0xd4,0xe8,0x19,0x03,0xbb,0x02);
  // clang-format on

  /**
   * Create a session to a remote shard
   *
   * @param debug_level         Debug level (0-3)
   * @param patience            Time out patience in seconds
   * @param owner               Owner info (not used)
   * @param src_nic_device      Client-side network device (e.g., mlx5_0, eth0)
   * @param src_ip_addr         Client-side IP address
   * @param dest_addr_with_port Server-side IP address and port (e.g. 10.0.0.21:11911, 9.1.75.6:11911:sockets)
   * @param other               Other optional parameters (e.g. { "security":"tls:auth" })
   *
   * @return Pointer to IMCAS instance. Use release_ref() to close.
   */
  virtual IMCAS* mcas_create_nsd(const unsigned, // debug_level
                                 const unsigned, // patience
                                 const string_view, // owner
                                 const string_view, // src_nic_device
                                 const string_view, // src_ip_addr
                                 const string_view, // dest_addr_with_port
                                 const string_view = string_view()) // other
  {
    throw API_exception("IMCAS_factory::mcas_create(debug_level,patience,owner,addr_with_port,nic_device) not implemented");
  }

  /**
   * Create a session to a remote shard (alternative)
   *
   * @param debug_level          Debug level
   * @param patience             Timeout patience in seconds
   * @param owner                Owner information (not used)
   * @param dest_addr_with_port  Destination server IP address and port
   * @param nic_device           Local NIC device to use (e.g., mlx5_0, eth0)
   * @param other                Other optional parameters (e.g. { "security":"tls:auth" })
   *
   * @return Pointer to IMCAS instance. Use release_ref() to close.
   */
  IMCAS* mcas_create(const unsigned    debug_level,
                     const unsigned    patience,
                     const string_view owner,
                     const string_view dest_addr_with_port,
                     const string_view nic_device,
                     const string_view other = string_view())
  {
    return mcas_create_nsd(debug_level, patience, owner, nic_device, string_view(), dest_addr_with_port, other);
  }
};

}  // namespace component

#endif

max_stars_repo_name: IBM/artemis

max_issues_repo_name: IBM/artemis

max_forks_repo_name: IBM/artemis


text:
//
//  @author raver119@gmail.com
//

#ifndef LIBND4J_BLAS_HELPER_H
#define LIBND4J_BLAS_HELPER_H

#include <pointercast.h>
#include <types/float16.h>
#include <cblas.h>
#include <helpers/logger.h>

#ifdef _WIN32
#define CUBLASWINAPI __stdcall
#else
#define CUBLASWINAPI
#endif

namespace nd4j {
    typedef enum{
        CUBLAS_STATUS_SUCCESS         =0,
        CUBLAS_STATUS_NOT_INITIALIZED =1,
        CUBLAS_STATUS_ALLOC_FAILED    =3,
        CUBLAS_STATUS_INVALID_VALUE   =7,
        CUBLAS_STATUS_ARCH_MISMATCH   =8,
        CUBLAS_STATUS_MAPPING_ERROR   =11,
        CUBLAS_STATUS_EXECUTION_FAILED=13,
        CUBLAS_STATUS_INTERNAL_ERROR  =14,
        CUBLAS_STATUS_NOT_SUPPORTED   =15,
        CUBLAS_STATUS_LICENSE_ERROR   =16
    } cublasStatus_t;

    typedef enum {
        CUBLAS_OP_N=0,
        CUBLAS_OP_T=1,
        CUBLAS_OP_C=2
    } cublasOperation_t;

    struct cublasContext;
    typedef struct cublasContext *cublasHandle_t;

    typedef enum
    {
	    CUDA_R_16F= 2,  /* real as a half */
	    CUDA_C_16F= 6,  /* complex as a pair of half numbers */
	    CUDA_R_32F= 0,  /* real as a float */
	    CUDA_C_32F= 4,  /* complex as a pair of float numbers */
	    CUDA_R_64F= 1,  /* real as a double */
	    CUDA_C_64F= 5,  /* complex as a pair of double numbers */
	    CUDA_R_8I = 3,  /* real as a signed char */
	    CUDA_C_8I = 7,  /* complex as a pair of signed char numbers */
	    CUDA_R_8U = 8,  /* real as a unsigned char */
	    CUDA_C_8U = 9,  /* complex as a pair of unsigned char numbers */
	    CUDA_R_32I= 10, /* real as a signed int */
	    CUDA_C_32I= 11, /* complex as a pair of signed int numbers */
	    CUDA_R_32U= 12, /* real as a unsigned int */
	    CUDA_C_32U= 13  /* complex as a pair of unsigned int numbers */
    } cublasDataType_t;

    typedef void (*CblasSgemv)(CBLAS_ORDER Layout,
                 CBLAS_TRANSPOSE TransA, int M, int N,
                 float alpha, float *A, int lda,
                 float *X, int incX, float beta,
                 float *Y, int incY);

    typedef void (*CblasDgemv)(CBLAS_ORDER Layout,
                 CBLAS_TRANSPOSE TransA, int M, int N,
                 double alpha, double *A, int lda,
                 double *X, int incX, double beta,
                 double *Y, int incY);

    typedef void (*CblasSgemm)(CBLAS_ORDER Layout, CBLAS_TRANSPOSE TransA,
                     CBLAS_TRANSPOSE TransB, int M, int N,
                     int K, float alpha, float *A,
                     int lda, float *B, int ldb,
                     float beta, float *C, int ldc);

    typedef void (*CblasDgemm)(CBLAS_ORDER Layout, CBLAS_TRANSPOSE TransA,
                     CBLAS_TRANSPOSE TransB, int M, int N,
                     int K, double alpha, double *A,
                     int lda, double *B, int ldb,
                     double beta, double *C, int ldc);

    typedef void (*CblasSgemmBatch)(CBLAS_ORDER Layout, CBLAS_TRANSPOSE *TransA_Array,
                           CBLAS_TRANSPOSE *TransB_Array, int *M_Array, int *N_Array,
                           int *K_Array, float *alpha_Array, float **A_Array,
                           int *lda_Array, float **B_Array, int *ldb_Array,
                           float *beta_Array, float **C_Array, int *ldc_Array,
                           int group_count, int *group_size);

    typedef void (*CblasDgemmBatch)(CBLAS_ORDER Layout, CBLAS_TRANSPOSE *TransA_Array,
                           CBLAS_TRANSPOSE *TransB_Array, int *M_Array, int *N_Array,
                           int *K_Array, double *alpha_Array, double **A_Array,
                           int *lda_Array, double **B_Array, int* ldb_Array,
                           double *beta_Array, double **C_Array, int *ldc_Array,
                           int group_count, int *group_size);

    typedef cublasStatus_t (CUBLASWINAPI *CublasSgemv)(cublasHandle_t handle,
                                                      cublasOperation_t trans,
                                                      int m,
                                                      int n,
                                                      float *alpha, /* host or device pointer */
                                                      float *A,
                                                      int lda,
                                                      float *x,
                                                      int incx,
                                                      float *beta,  /* host or device pointer */
                                                      float *y,
                                                      int incy);

    typedef cublasStatus_t (CUBLASWINAPI *CublasDgemv)(cublasHandle_t handle,
                                                      cublasOperation_t trans,
                                                      int m,
                                                      int n,
                                                      double *alpha, /* host or device pointer */
                                                      double *A,
                                                      int lda,
                                                      double *x,
                                                      int incx,
                                                      double *beta, /* host or device pointer */
                                                      double *y,
                                                      int incy);

    typedef cublasStatus_t (CUBLASWINAPI *CublasHgemm)(cublasHandle_t handle,
                                                      cublasOperation_t transa,
                                                      cublasOperation_t transb,
                                                      int m,
                                                      int n,
                                                      int k,
                                                      __half *alpha, /* host or device pointer */
                                                      __half *A,
                                                      int lda,
                                                      __half *B,
                                                      int ldb,
                                                      __half *beta, /* host or device pointer */
                                                      __half *C,
                                                      int ldc);

    typedef cublasStatus_t (CUBLASWINAPI *CublasSgemm)(cublasHandle_t handle,
                                                      cublasOperation_t transa,
                                                      cublasOperation_t transb,
                                                      int m,
                                                      int n,
                                                      int k,
                                                      float *alpha, /* host or device pointer */
                                                      float *A,
                                                      int lda,
                                                      float *B,
                                                      int ldb,
                                                      float *beta, /* host or device pointer */
                                                      float *C,
                                                      int ldc);

    typedef cublasStatus_t (CUBLASWINAPI *CublasDgemm)(cublasHandle_t handle,
                                                      cublasOperation_t transa,
                                                      cublasOperation_t transb,
                                                      int m,
                                                      int n,
                                                      int k,
                                                      double *alpha, /* host or device pointer */
                                                      double *A,
                                                      int lda,
                                                      double *B,
                                                      int ldb,
                                                      double *beta, /* host or device pointer */
                                                      double *C,
                                                      int ldc);

    typedef cublasStatus_t (CUBLASWINAPI *CublasSgemmEx)(cublasHandle_t handle,
                                                      cublasOperation_t transa,
                                                      cublasOperation_t transb,
                                                      int m,
                                                      int n,
                                                      int k,
                                                      float *alpha, /* host or device pointer */
                                                      void *A,
                                                      cublasDataType_t Atype,
                                                      int lda,
                                                      void *B,
                                                      cublasDataType_t Btype,
                                                      int ldb,
                                                      float *beta, /* host or device pointer */
                                                      void *C,
                                                      cublasDataType_t Ctype,
                                                      int ldc);

    typedef cublasStatus_t (CUBLASWINAPI *CublasHgemmBatched)(cublasHandle_t handle,
                                                          cublasOperation_t transa,
                                                          cublasOperation_t transb,
                                                          int m,
                                                          int n,
                                                          int k,
                                                          __half *alpha,  /* host or device pointer */
                                                          __half *Aarray[],
                                                          int lda,
                                                          __half *Barray[],
                                                          int ldb,
                                                          __half *beta,   /* host or device pointer */
                                                          __half *Carray[],
                                                          int ldc,
                                                          int batchCount);

    typedef cublasStatus_t (CUBLASWINAPI *CublasSgemmBatched)(cublasHandle_t handle,
                                                          cublasOperation_t transa,
                                                          cublasOperation_t transb,
                                                          int m,
                                                          int n,
                                                          int k,
                                                          float *alpha,  /* host or device pointer */
                                                          float *Aarray[],
                                                          int lda,
                                                          float *Barray[],
                                                          int ldb,
                                                          float *beta,   /* host or device pointer */
                                                          float *Carray[],
                                                          int ldc,
                                                          int batchCount);

    typedef cublasStatus_t (CUBLASWINAPI *CublasDgemmBatched)(cublasHandle_t handle,
                                                          cublasOperation_t transa,
                                                          cublasOperation_t transb,
                                                          int m,
                                                          int n,
                                                          int k,
                                                          double *alpha,  /* host or device pointer */
                                                          double *Aarray[],
                                                          int lda,
                                                          double *Barray[],
                                                          int ldb,
                                                          double *beta,  /* host or device pointer */
                                                          double *Carray[],
                                                          int ldc,
                                                          int batchCount);

    enum BlasFunctions {
        GEMV = 0,
        GEMM = 1,
    };

    class BlasHelper {
    private:
        static BlasHelper* _instance;

		bool _hasHgemv = false;
		bool _hasHgemm = false;
		bool _hasHgemmBatch = false;

        bool _hasSgemv = false;
        bool _hasSgemm = false;
        bool _hasSgemmBatch = false;

        bool _hasDgemv = false;
        bool _hasDgemm = false;
        bool _hasDgemmBatch = false;

        CblasSgemv cblasSgemv;
        CblasDgemv cblasDgemv;
        CblasSgemm cblasSgemm;
        CblasDgemm cblasDgemm;
        CblasSgemmBatch cblasSgemmBatch;
        CblasDgemmBatch cblasDgemmBatch;

        CublasSgemv cublasSgemv;
        CublasDgemv cublasDgemv;
        CublasHgemm cublasHgemm;
        CublasSgemm cublasSgemm;
        CublasDgemm cublasDgemm;
        CublasSgemmEx cublasSgemmEx;
        CublasHgemmBatched cublasHgemmBatched;
        CublasSgemmBatched cublasSgemmBatched;
        CublasDgemmBatched cublasDgemmBatched;

    public:
        static BlasHelper* getInstance();

        void initializeFunctions(Nd4jPointer *functions);
		void initializeDeviceFunctions(Nd4jPointer *functions);

        template <typename T>
        bool hasGEMV();

        template <typename T>
        bool hasGEMM();

        template <typename T>
        bool hasBatchedGEMM();

        CblasSgemv sgemv();
        CblasDgemv dgemv();

        CblasSgemm sgemm();
        CblasDgemm dgemm();

        CblasSgemmBatch sgemmBatched();
        CblasDgemmBatch dgemmBatched();
    };
}

#endif

ext: h


text:
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#pragma once
#include <windows.h>

// Include ABI composition headers for interop with DCOMP surface handle from MediaEngine
#include <windows.ui.composition.h>
#include <windows.ui.composition.interop.h>

// Include prior to WinRT Headers
#include <wil/cppwinrt.h>

// WinRT Headers
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.ApplicationModel.Core.h>
#include <winrt/Windows.UI.Core.h>
#include <winrt/Windows.UI.Composition.h>
#include <winrt/Windows.UI.Input.h>
#include <winrt/Windows.Media.Protection.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Storage.Streams.h>
#include <winrt/Windows.Web.Http.Headers.h>
#include <winrt/Windows.Data.Xml.Dom.h>
#include <winrt/Windows.Security.Cryptography.h>
#include <winrt/Windows.ApplicationModel.h>

// Direct3D
#include <d3d11.h>

// Windows Implementation Library
#include <wil/com.h>
#include <wil/resource.h>
#include <wil/result_macros.h>

// MediaFoundation headers
#include <mfapi.h>
#include <mferror.h>
#include <mfmediaengine.h>
#include <mfidl.h>
#include <mfcontentdecryptionmodule.h>

// STL headers
#include <functional>
#include <memory>
#include <string>
#include <vector>
#include <tuple>
#include <array>

// GSL (C++ Guidelines Support Library)
#include <gsl/span>

max_stars_repo_name: microsoft/media-foundation

max_issues_repo_name: QPC-database/media-foundation

max_forks_repo_name: QPC-database/media-foundation


text:
/* multifit/multilinear.c
 *
 * Copyright (C) 2000 Brian Gough
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <config.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_multifit.h>
#include <gsl/gsl_blas.h>
#include <gsl/gsl_linalg.h>

/* Fit
 *
 *  y = X c
 *
 *  where X is an M x N matrix of M observations for N variables.
 *
 */

int
gsl_multifit_linear (const gsl_matrix * X,
		     const gsl_vector * y,
		     gsl_vector * c,
		     gsl_matrix * cov,
		     double *chisq, gsl_multifit_linear_workspace * work)
{
  if (X->size1 != y->size)
    {
      GSL_ERROR
	("number of observations in y does not match rows of matrix X",
	 GSL_EBADLEN);
    }
  else if (X->size2 != c->size)
    {
      GSL_ERROR ("number of parameters c does not match columns of matrix X",
		 GSL_EBADLEN);
    }
  else if (cov->size1 != cov->size2)
    {
      GSL_ERROR ("covariance matrix is not square", GSL_ENOTSQR);
    }
  else if (c->size != cov->size1)
    {
      GSL_ERROR
	("number of parameters does not match size of covariance matrix",
	 GSL_EBADLEN);
    }
  else if (X->size1 != work->n || X->size2 != work->p)
    {
      GSL_ERROR
	("size of workspace does not match size of observation matrix",
	 GSL_EBADLEN);
    }
  else
    {
      const size_t n = X->size1;
      const size_t p = X->size2;

      size_t i, j;

      gsl_matrix *A = work->A;
      gsl_matrix *Q = work->Q;
      gsl_matrix *QSI = work->QSI;
      gsl_vector *S = work->S;
      gsl_vector *xt = work->xt;
      gsl_vector *D = work->D;

      /* Copy X to workspace,  A <= X */

      gsl_matrix_memcpy (A, X);

      /* Balance the columns of the matrix A */

      gsl_linalg_balance_columns (A, D);

      /* Decompose A into U S Q^T */

      gsl_linalg_SV_decomp_mod (A, QSI, Q, S, xt);

      /* Solve y = A c for c */

      gsl_blas_dgemv (CblasTrans, 1.0, A, y, 0.0, xt);

      /* Scale the matrix Q,  Q' = Q S^-1 */

      gsl_matrix_memcpy (QSI, Q);

      for (j = 0; j < p; j++)
	{
	  gsl_vector_view column = gsl_matrix_column (QSI, j);
	  double alpha = gsl_vector_get (S, j);
	  if (alpha != 0)
	    alpha = 1.0 / alpha;
	  gsl_vector_scale (&column.vector, alpha);
	}

      gsl_vector_set_zero (c);

      gsl_blas_dgemv (CblasNoTrans, 1.0, QSI, xt, 0.0, c);

      /* Unscale the balancing factors */

      gsl_vector_div (c, D);

      /* Compute chisq, from residual r = y - X c */

      {
	double s2 = 0, r2 = 0;

	for (i = 0; i < n; i++)
	  {
	    double yi = gsl_vector_get (y, i);
	    gsl_vector_const_view row = gsl_matrix_const_row (X, i);
	    double y_est, ri;
	    gsl_blas_ddot (&row.vector, c, &y_est);
	    ri = yi - y_est;
	    r2 += ri * ri;
	  }

	s2 = r2 / (n - p);

	*chisq = r2;

	/* Form variance-covariance matrix cov = s2 * (Q S^-1) (Q S^-1)^T */

	for (i = 0; i < p; i++)
	  {
	    gsl_vector_view row_i = gsl_matrix_row (QSI, i);
	    double d_i = gsl_vector_get (D, i);

	    for (j = i; j < p; j++)
	      {
		gsl_vector_view row_j = gsl_matrix_row (QSI, j);
		double d_j = gsl_vector_get (D, j);
		double s;

		gsl_blas_ddot (&row_i.vector, &row_j.vector, &s);

		gsl_matrix_set (cov, i, j, s * s2 / (d_i * d_j));
		gsl_matrix_set (cov, j, i, s * s2 / (d_i * d_j));
	      }
	  }
      }

      return GSL_SUCCESS;
    }
}

int
gsl_multifit_wlinear (const gsl_matrix * X,
		      const gsl_vector * w,
		      const gsl_vector * y,
		      gsl_vector * c,
		      gsl_matrix * cov,
		      double *chisq, gsl_multifit_linear_workspace * work)
{
  if (X->size1 != y->size)
    {
      GSL_ERROR
	("number of observations in y does not match rows of matrix X",
	 GSL_EBADLEN);
    }
  else if (X->size2 != c->size)
    {
      GSL_ERROR ("number of parameters c does not match columns of matrix X",
		 GSL_EBADLEN);
    }
  else if (w->size != y->size)
    {
      GSL_ERROR ("number of weights does not match number of observations",
		 GSL_EBADLEN);
    }
  else if (cov->size1 != cov->size2)
    {
      GSL_ERROR ("covariance matrix is not square", GSL_ENOTSQR);
    }
  else if (c->size != cov->size1)
    {
      GSL_ERROR
	("number of parameters does not match size of covariance matrix",
	 GSL_EBADLEN);
    }
  else if (X->size1 != work->n || X->size2 != work->p)
    {
      GSL_ERROR
	("size of workspace does not match size of observation matrix",
	 GSL_EBADLEN);
    }
  else
    {
      const size_t n = X->size1;
      const size_t p = X->size2;

      size_t i, j;

      gsl_matrix *A = work->A;
      gsl_matrix *Q = work->Q;
      gsl_matrix *QSI = work->QSI;
      gsl_vector *S = work->S;
      gsl_vector *t = work->t;
      gsl_vector *xt = work->xt;
      gsl_vector *D = work->D;

      /* Scale X,  A = sqrt(w) X */

      gsl_matrix_memcpy (A, X);

      for (i = 0; i < n; i++)
	{
	  double wi = gsl_vector_get (w, i);

	  if (wi < 0)
	    wi = 0;

	  {
	    gsl_vector_view row = gsl_matrix_row (A, i);
	    gsl_vector_scale (&row.vector, sqrt (wi));
	  }
	}

      /* Balance the columns of the matrix A */

      gsl_linalg_balance_columns (A, D);

      /* Decompose A into U S Q^T */

      gsl_linalg_SV_decomp_mod (A, QSI, Q, S, xt);

      /* Solve sqrt(w) y = A c for c, by first computing t = sqrt(w) y */

      for (i = 0; i < n; i++)
	{
	  double wi = gsl_vector_get (w, i);
	  double yi = gsl_vector_get (y, i);
	  if (wi < 0)
	    wi = 0;
	  gsl_vector_set (t, i, sqrt (wi) * yi);
	}

      gsl_blas_dgemv (CblasTrans, 1.0, A, t, 0.0, xt);

      /* Scale the matrix Q,  Q' = Q S^-1 */

      gsl_matrix_memcpy (QSI, Q);

      for (j = 0; j < p; j++)
	{
	  gsl_vector_view column = gsl_matrix_column (QSI, j);
	  double alpha = gsl_vector_get (S, j);
	  if (alpha != 0)
	    alpha = 1.0 / alpha;
	  gsl_vector_scale (&column.vector, alpha);
	}

      gsl_vector_set_zero (c);

      /* Solution */

      gsl_blas_dgemv (CblasNoTrans, 1.0, QSI, xt, 0.0, c);

      /* Unscale the balancing factors */

      gsl_vector_div (c, D);

      /* Form covariance matrix cov = (Q S^-1) (Q S^-1)^T */

      for (i = 0; i < p; i++)
	{
	  gsl_vector_view row_i = gsl_matrix_row (QSI, i);
	  double d_i = gsl_vector_get (D, i);

	  for (j = i; j < p; j++)
	    {
	      gsl_vector_view row_j = gsl_matrix_row (QSI, j);
	      double d_j = gsl_vector_get (D, j);
	      double s;

	      gsl_blas_ddot (&row_i.vector, &row_j.vector, &s);

	      gsl_matrix_set (cov, i, j, s / (d_i * d_j));
	      gsl_matrix_set (cov, j, i, s / (d_i * d_j));
	    }
	}

      /* Compute chisq, from residual r = y - X c */

      {
	double r2 = 0;

	for (i = 0; i < n; i++)
	  {
	    double yi = gsl_vector_get (y, i);
	    double wi = gsl_vector_get (w, i);
	    gsl_vector_const_view row = gsl_matrix_const_row (X, i);
	    double y_est, ri;
	    gsl_blas_ddot (&row.vector, c, &y_est);
	    ri = yi - y_est;
	    r2 += wi * ri * ri;
	  }

	*chisq = r2;
      }

      return GSL_SUCCESS;
    }
}

ext: c


text:
#include <r.h>

#include <string.h>
#include <math.h>
#include <assert.h>
#include <stdlib.h>

#include <gsl/gsl_cdf.h>

static void uniformly_distributed(uint64_t (*f)(void))
{
    const size_t B = 10, N = 100000;
    size_t boxes[B]; memset(boxes, 0, sizeof(boxes));

    for(size_t i = 0; i < N; i++) {
        boxes[f() % B] += 1;
    }

    double chi2 = 0;
    for(size_t i = 0; i < B; i++) {
        const double E = (double)N/B;
        const double err = (double)boxes[i] - E;
        chi2 += err*err/E;
    }

    assert(chi2 <= gsl_cdf_chisq_Pinv(0.95, B-1));
}

static void normally_distributed(float (*f)(void))
{
    const size_t B = 5, N = 1000;
    size_t boxes[B+1]; memset(boxes, 0, sizeof(boxes));

    float stddev = 2;
    for(size_t i = 0; i < N; i++) {
        size_t j = floor(fabsf(f()) * stddev);
        boxes[MIN(j, B)] += 1;
    }

    double E = 2*N*gsl_cdf_gaussian_Q(B, stddev);
    double err = (double)boxes[B] - E;
    double chi2 = err*err/E;
    for(size_t i = 0; i < B; i++) {
        E = N * 2 * (gsl_cdf_gaussian_P(i+1, stddev) - gsl_cdf_gaussian_P(i, stddev));
        err = (double)boxes[i] - E;
        chi2 += err*err/E;
    }

    assert(chi2 <= gsl_cdf_chisq_Pinv(0.95, B));
}

void xorshift_tests(void)
{
    xorshift_state_initialize();

    TEST(xorshift64_is_uniform, {
         uniformly_distributed(xorshift64_i);
    });

    TEST(xorshift128plus_is_uniform, {
          uniformly_distributed(xorshift128plus_i);
    });

    TEST(normal_dist_is_normal, {
          normally_distributed(normal_dist_i);
    });

    TEST_ABORT(xorshift64_is_not_normal, {
        float f() { return uniform_float(xorshift64_i()); }
        normally_distributed(f);
    });

    TEST_ABORT(normal_dist_is_not_uniform, {
        uint64_t f() { return llrint(fabsf(normal_dist_i())); }
        uniformly_distributed(f);
    });

    TEST_ABORT(normal_dist_test_should_respect_stddev, {
        float f() { return 2*normal_dist_i(); }
        normally_distributed(f);
    });
}

max_stars_repo_name: rootmos/libr

max_issues_repo_name: rootmos/libr

max_forks_repo_name: rootmos/libr


text:
/* specfunc/legendre_poly.c
 *
 * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/* Author:  G. Jungman */

#include <config.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_errno.h>
#include "gsl_sf_bessel.h"
#include "gsl_sf_exp.h"
#include "gsl_sf_gamma.h"
#include "gsl_sf_log.h"
#include "gsl_sf_pow_int.h"
#include "gsl_sf_legendre.h"

#include "error.h"

/*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/

int
gsl_sf_legendre_P1_e(double x, gsl_sf_result * result)
{
  /* CHECK_POINTER(result) */

  {
    result->val = x;
    result->err = 0.0;
    return GSL_SUCCESS;
  }
}

int
gsl_sf_legendre_P2_e(double x, gsl_sf_result * result)
{
  /* CHECK_POINTER(result) */

  {
    result->val = 0.5*(3.0*x*x - 1.0);
    result->err = GSL_DBL_EPSILON * (fabs(3.0*x*x) + 1.0);
    return GSL_SUCCESS;
  }
}

int
gsl_sf_legendre_P3_e(double x, gsl_sf_result * result)
{
  /* CHECK_POINTER(result) */

  {
    result->val = 0.5*x*(5.0*x*x - 3.0);
    result->err = GSL_DBL_EPSILON * (fabs(result->val) + 0.5 * fabs(x) * (fabs(5.0*x*x) + 3.0));
    return GSL_SUCCESS;
  }
}

int
gsl_sf_legendre_Pl_e(const int l, const double x, gsl_sf_result * result)
{
  /* CHECK_POINTER(result) */

  if(l < 0 || x < -1.0 || x > 1.0) {
    DOMAIN_ERROR(result);
  }
  else if(l == 0) {
    result->val = 1.0;
    result->err = 0.0;
    return GSL_SUCCESS;
  }
  else if(l == 1) {
    result->val = x;
    result->err = 0.0;
    return GSL_SUCCESS;
  }
  else if(l == 2) {
    result->val = 0.5 * (3.0*x*x - 1.0);
    result->err = 3.0 * GSL_DBL_EPSILON * fabs(result->val);
    return GSL_SUCCESS;
  }
  else if(x == 1.0) {
    result->val = 1.0;
    result->err = 0.0;
    return GSL_SUCCESS;
  }
  else if(x == -1.0) {
    result->val = ( GSL_IS_ODD(l) ? -1.0 : 1.0 );
    result->err = 0.0;
    return GSL_SUCCESS;
  }
  else if(l < 100000) {
    /* Compute by upward recurrence on l.
     */
    double p_mm   = 1.0;     /* P_0(x) */
    double p_mmp1 = x;	    /* P_1(x) */
    double p_ell = p_mmp1;
    int ell;

    for(ell=2; ell <= l; ell++){
      p_ell = (x*(2*ell-1)*p_mmp1 - (ell-1)*p_mm) / ell;
      p_mm = p_mmp1;
      p_mmp1 = p_ell;
    }

    result->val = p_ell;
    result->err = (0.5 * ell + 1.0) * GSL_DBL_EPSILON * fabs(p_ell);
    return GSL_SUCCESS;
  }
  else {
    /* Asymptotic expansion.
     * [Olver, p. 473]
     */
    double u  = l + 0.5;
    double th = acos(x);
    gsl_sf_result J0;
    gsl_sf_result Jm1;
    int stat_J0  = gsl_sf_bessel_J0_e(u*th, &J0);
    int stat_Jm1 = gsl_sf_bessel_Jn_e(-1, u*th, &Jm1);
    double pre;
    double B00;
    double c1;

    /* B00 = 1/8 (1 - th cot(th) / th^2
     * pre = sqrt(th/sin(th))
     */
    if(th < GSL_ROOT4_DBL_EPSILON) {
      B00 = (1.0 + th*th/15.0)/24.0;
      pre = 1.0 + th*th/12.0;
    }
    else {
      double sin_th = sqrt(1.0 - x*x);
      double cot_th = x / sin_th;
      B00 = 1.0/8.0 * (1.0 - th * cot_th) / (th*th);
      pre = sqrt(th/sin_th);
    }

    c1 = th/u * B00;

    result->val  = pre * (J0.val + c1 * Jm1.val);
    result->err  = pre * (J0.err + fabs(c1) * Jm1.err);
    result->err += GSL_SQRT_DBL_EPSILON * fabs(result->val);

    return GSL_ERROR_SELECT_2(stat_J0, stat_Jm1);
  }
}

int
gsl_sf_legendre_Pl_array(const int lmax, const double x, double * result_array)
{
  /* CHECK_POINTER(result_array) */

  if(lmax < 0 || x < -1.0 || x > 1.0) {
    GSL_ERROR ("domain error", GSL_EDOM);
  }
  else if(lmax == 0) {
    result_array[0] = 1.0;
    return GSL_SUCCESS;
  }
  else if(lmax == 1) {
    result_array[0] = 1.0;
    result_array[1] = x;
    return GSL_SUCCESS;
  }
  else {
    double p_mm   = 1.0;    /* P_0(x) */
    double p_mmp1 = x;	    /* P_1(x) */
    double p_ell = p_mmp1;
    int ell;

    result_array[0] = 1.0;
    result_array[1] = x;

    for(ell=2; ell <= lmax; ell++){
      p_ell = (x*(2*ell-1)*p_mmp1 - (ell-1)*p_mm) / ell;
      p_mm = p_mmp1;
      p_mmp1 = p_ell;
      result_array[ell] = p_ell;
    }

    return GSL_SUCCESS;
  }
}

int
gsl_sf_legendre_Plm_e(const int l, const int m, const double x, gsl_sf_result * result)
{
  /* If l is large and m is large, then we have to worry
   * about overflow. Calculate an approximate exponent which
   * measures the normalization of this thing.
   */
  double dif = l-m;
  double sum = l+m;
  double exp_check = 0.5 * log(2.0*l+1.0)
                   + 0.5 * dif * (log(dif)-1.0)
                   - 0.5 * sum * (log(sum)-1.0);

  /* CHECK_POINTER(result) */

  if(m < 0 || l < m || x < -1.0 || x > 1.0) {
    DOMAIN_ERROR(result);
  }
  else if(exp_check < GSL_LOG_DBL_MIN + 10.0){
    /* Bail out. */
    OVERFLOW_ERROR(result);
  }
  else {
    /* Account for the error due to the
     * representation of 1-x.
     */
    const double err_amp = 1.0 / (GSL_DBL_EPSILON + fabs(1.0-fabs(x)));

    double p_mm;     /* P_m^m(x) */
    double p_mmp1;   /* P_{m+1}^m(x) */

    /* Calculate P_m^m from the analytic result:
     *          P_m^m(x) = (-1)^m (2m-1)!! (1-x^2)^(m/2) , m > 0
     */
    p_mm = 1.0;
    if(m > 0){
      double root_factor = sqrt(1.0-x)*sqrt(1.0+x);
      double fact_coeff = 1.0;
      int i;
      for(i=1; i<=m; i++) {
        p_mm *= -fact_coeff * root_factor;
        fact_coeff += 2.0;
      }
    }

    /* Calculate P_{m+1}^m. */
    p_mmp1 = x * (2*m + 1) * p_mm;

    if(l == m){
      result->val = p_mm;
      result->err = err_amp * 2.0 * GSL_DBL_EPSILON * fabs(p_mm);
      return GSL_SUCCESS;
    }
    else if(l == m + 1) {
      result->val = p_mmp1;
      result->err = err_amp * 2.0 * GSL_DBL_EPSILON * fabs(p_mmp1);
      return GSL_SUCCESS;
    }
    else{
      double p_ell = 0.0;
      int ell;

      /* Compute P_l^m, l > m+1 by upward recurrence on l. */
      for(ell=m+2; ell <= l; ell++){
        p_ell = (x*(2*ell-1)*p_mmp1 - (ell+m-1)*p_mm) / (ell-m);
        p_mm = p_mmp1;
        p_mmp1 = p_ell;
      }

      result->val = p_ell;
      result->err = err_amp * (0.5*(l-m) + 1.0) * GSL_DBL_EPSILON * fabs(p_ell);

      return GSL_SUCCESS;
    }
  }
}

int
gsl_sf_legendre_Plm_array(const int lmax, const int m, const double x, double * result_array)
{
  /* If l is large and m is large, then we have to worry
   * about overflow. Calculate an approximate exponent which
   * measures the normalization of this thing.
   */
  double dif = lmax-m;
  double sum = lmax+m;
  double exp_check = 0.5 * log(2.0*lmax+1.0)
                     + 0.5 * dif * (log(dif)-1.0)
                     - 0.5 * sum * (log(sum)-1.0);

  /* CHECK_POINTER(result_array) */

  if(m < 0 || lmax < m || x < -1.0 || x > 1.0) {
    GSL_ERROR ("error", GSL_EDOM);
  }
  else if(m > 0 && (x == 1.0 || x == -1.0)) {
    int ell;
    for(ell=m; ell<=lmax; ell++) result_array[ell-m] = 0.0;
    return GSL_SUCCESS;
  }
  else if(exp_check < GSL_LOG_DBL_MIN + 10.0){
    /* Bail out.
     */
    GSL_ERROR ("error", GSL_EOVRFLW);
  }
  else {
    double p_mm;                 /* P_m^m(x)     */
    double p_mmp1;               /* P_{m+1}^m(x) */

    /* Calculate P_m^m from the analytic result:
     *          P_m^m(x) = (-1)^m (2m-1)!! (1-x^2)^(m/2) , m > 0
     */
    p_mm = 1.0;
    if(m > 0){
      double root_factor = sqrt(1.0-x)*sqrt(1.0+x);
      double fact_coeff = 1.0;
      int i;
      for(i=1; i<=m; i++){
        p_mm *= -fact_coeff * root_factor;
        fact_coeff += 2.0;
      }
    }

    /* Calculate P_{m+1}^m. */
    p_mmp1 = x * (2*m + 1) * p_mm;

    if(lmax == m){
      result_array[0] = p_mm;
      return GSL_SUCCESS;
    }
    else if(lmax == m + 1) {
      result_array[0] = p_mm;
      result_array[1] = p_mmp1;
      return GSL_SUCCESS;
    }
    else{
      double p_ell;
      int ell;

      result_array[0] = p_mm;
      result_array[1] = p_mmp1;

      /* Compute P_l^m, l >= m+2, by upward recursion on l. */
      for(ell=m+2; ell <= lmax; ell++){
        p_ell = (x*(2*ell-1)*p_mmp1 - (ell+m-1)*p_mm) / (ell-m);
        p_mm = p_mmp1;
        p_mmp1 = p_ell;
        result_array[ell-m] = p_ell;
      }

      return GSL_SUCCESS;
    }
  }
}

int
gsl_sf_legendre_sphPlm_e(const int l, int m, const double x, gsl_sf_result * result)
{
  /* CHECK_POINTER(result) */

  if(m < 0 || l < m || x < -1.0 || x > 1.0) {
    DOMAIN_ERROR(result);
  }
  else if(m == 0) {
    gsl_sf_result P;
    int stat_P = gsl_sf_legendre_Pl_e(l, x, &P);
    double pre = sqrt((2.0*l + 1.0)/(4.0*M_PI));
    result->val  = pre * P.val;
    result->err  = pre * P.err;
    result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
    return stat_P;
  }
  else if(x == 1.0 || x == -1.0) {
    /* m > 0 here */
    result->val = 0.0;
    result->err = 0.0;
    return GSL_SUCCESS;
  }
  else {
    /* m > 0 and |x| < 1 here */

    /* Starting value for recursion.
     * Y_m^m(x) = sqrt( (2m+1)/(4pi m) gamma(m+1/2)/gamma(m) ) (-1)^m (1-x^2)^(m/2) / pi^(1/4)
     */
    gsl_sf_result lncirc;
    gsl_sf_result lnpoch;
    double lnpre_val;
    double lnpre_err;
    gsl_sf_result ex_pre;
    double sr;
    const double sgn = ( GSL_IS_ODD(m) ? -1.0 : 1.0);
    const double y_mmp1_factor = x * sqrt(2.0*m + 3.0);
    double y_mm, y_mm_err;
    double y_mmp1;
    gsl_sf_log_1plusx_e(-x*x, &lncirc);
    gsl_sf_lnpoch_e(m, 0.5, &lnpoch);  /* Gamma(m+1/2)/Gamma(m) */
    lnpre_val = -0.25*M_LNPI + 0.5 * (lnpoch.val + m*lncirc.val);
    lnpre_err = 0.25*M_LNPI*GSL_DBL_EPSILON + 0.5 * (lnpoch.err + fabs(m)*lncirc.err);
    gsl_sf_exp_err_e(lnpre_val, lnpre_err, &ex_pre);
    sr    = sqrt((2.0+1.0/m)/(4.0*M_PI));
    y_mm   = sgn * sr * ex_pre.val;
    y_mmp1 = y_mmp1_factor * y_mm;
    y_mm_err  = 2.0 * GSL_DBL_EPSILON * fabs(y_mm) + sr * ex_pre.err;
    y_mm_err *= 1.0 + 1.0/(GSL_DBL_EPSILON + fabs(1.0-x));

    if(l == m){
      result->val  = y_mm;
      result->err  = y_mm_err;
      result->err += 2.0 * GSL_DBL_EPSILON * fabs(y_mm);
      return GSL_SUCCESS;
    }
    else if(l == m + 1) {
      result->val  = y_mmp1;
      result->err  = fabs(y_mmp1_factor) * y_mm_err;
      result->err += 2.0 * GSL_DBL_EPSILON * fabs(y_mmp1);
      return GSL_SUCCESS;
    }
    else{
      double y_ell = 0.0;
      int ell;

      /* Compute Y_l^m, l > m+1, upward recursion on l. */
      for(ell=m+2; ell <= l; ell++){
        const double rat1 = (double)(ell-m)/(double)(ell+m);
	const double rat2 = (ell-m-1.0)/(ell+m-1.0);
        const double factor1 = sqrt(rat1*(2*ell+1)*(2*ell-1));
        const double factor2 = sqrt(rat1*rat2*(2*ell+1)/(2*ell-3));
        y_ell = (x*y_mmp1*factor1 - (ell+m-1)*y_mm*factor2) / (ell-m);
        y_mm   = y_mmp1;
        y_mmp1 = y_ell;
      }

      result->val  = y_ell;
      result->err  = (0.5*(l-m) + 1.0) * GSL_DBL_EPSILON * fabs(y_ell);
      result->err += fabs(y_mm_err/y_mm) * fabs(y_ell);

      return GSL_SUCCESS;
    }
  }
}

int
gsl_sf_legendre_sphPlm_array(const int lmax, int m, const double x, double * result_array)
{
  /* CHECK_POINTER(result_array) */

  if(m < 0 || lmax < m || x < -1.0 || x > 1.0) {
    GSL_ERROR ("error", GSL_EDOM);
  }
  else if(m > 0 && (x == 1.0 || x == -1.0)) {
    int ell;
    for(ell=m; ell<=lmax; ell++) result_array[ell-m] = 0.0;
    return GSL_SUCCESS;
  }
  else {
    double y_mm;
    double y_mmp1;

    if(m == 0) {
      y_mm   = 0.5/M_SQRTPI;          /* Y00 = 1/sqrt(4pi) */
      y_mmp1 = x * M_SQRT3 * y_mm;
    }
    else {
      /* |x| < 1 here */

      gsl_sf_result lncirc;
      gsl_sf_result lnpoch;
      double lnpre;
      const double sgn = ( GSL_IS_ODD(m) ? -1.0 : 1.0);
      gsl_sf_log_1plusx_e(-x*x, &lncirc);
      gsl_sf_lnpoch_e(m, 0.5, &lnpoch);  /* Gamma(m+1/2)/Gamma(m) */
      lnpre = -0.25*M_LNPI + 0.5 * (lnpoch.val + m*lncirc.val);
      y_mm   = sqrt((2.0+1.0/m)/(4.0*M_PI)) * sgn * exp(lnpre);
      y_mmp1 = x * sqrt(2.0*m + 3.0) * y_mm;
    }

    if(lmax == m){
      result_array[0] = y_mm;
      return GSL_SUCCESS;
    }
    else if(lmax == m + 1) {
      result_array[0] = y_mm;
      result_array[1] = y_mmp1;
      return GSL_SUCCESS;
    }
    else{
      double y_ell;
      int ell;

      result_array[0] = y_mm;
      result_array[1] = y_mmp1;

      /* Compute Y_l^m, l > m+1, upward recursion on l. */
      for(ell=m+2; ell <= lmax; ell++){
        const double rat1 = (double)(ell-m)/(double)(ell+m);
	const double rat2 = (ell-m-1.0)/(ell+m-1.0);
        const double factor1 = sqrt(rat1*(2*ell+1)*(2*ell-1));
        const double factor2 = sqrt(rat1*rat2*(2*ell+1)/(2*ell-3));
        y_ell = (x*y_mmp1*factor1 - (ell+m-1)*y_mm*factor2) / (ell-m);
        y_mm   = y_mmp1;
        y_mmp1 = y_ell;
	result_array[ell-m] = y_ell;
      }
    }

    return GSL_SUCCESS;
  }
}

#ifndef HIDE_INLINE_STATIC
int
gsl_sf_legendre_array_size(const int lmax, const int m)
{
  return lmax-m+1;
}
#endif

/*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/

#include "eval.h"

double gsl_sf_legendre_P1(const double x)
{
  EVAL_RESULT(gsl_sf_legendre_P1_e(x, &result));
}

double gsl_sf_legendre_P2(const double x)
{
  EVAL_RESULT(gsl_sf_legendre_P2_e(x, &result));
}

double gsl_sf_legendre_P3(const double x)
{
  EVAL_RESULT(gsl_sf_legendre_P3_e(x, &result));
}

double gsl_sf_legendre_Pl(const int l, const double x)
{
  EVAL_RESULT(gsl_sf_legendre_Pl_e(l, x, &result));
}

double gsl_sf_legendre_Plm(const int l, const int m, const double x)
{
  EVAL_RESULT(gsl_sf_legendre_Plm_e(l, m, x, &result));
}

double gsl_sf_legendre_sphPlm(const int l, const int m, const double x)
{
  EVAL_RESULT(gsl_sf_legendre_sphPlm_e(l, m, x, &result));
}


text:
/*
   Copyright [2017-2021] [IBM Corporation]
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
       http://www.apache.org/licenses/LICENSE-2.0
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#ifndef _MCAS_HSTORE_POOL_MANAGER_H
#define _MCAS_HSTORE_POOL_MANAGER_H

#include <api/kvstore_itf.h> /* status_t */

#include "alloc_key.h" /* AK_FORMAL */
#include "pool_error.h"

#include <common/logging.h> /* log_source */
#include <common/string_view.h>
#include <nupm/region_descriptor.h>
#include <gsl/pointers>
#include <sys/uio.h>
#include <cstddef>
#include <functional>
#include <string>
#include <system_error>

struct pool_path;

struct dax_manager;

template <typename Pool>
  struct pool_manager
    : protected common::log_source
  {
    using string_view = common::string_view;
    pool_manager(unsigned debug_level_) : common::log_source(debug_level_) {}
    virtual ~pool_manager() {}

    virtual void pool_create_check(const std::size_t size_) = 0;

    virtual void pool_close_check(const string_view) = 0;

    virtual nupm::region_descriptor pool_get_regions(const Pool &) const = 0;

    /*
     * throws pool_error if create_region fails
     */
    virtual auto pool_create_1(
      const pool_path &path_
      , std::size_t size_
    ) -> nupm::region_descriptor = 0;

    virtual auto pool_create_2(
      AK_FORMAL
      const nupm::region_descriptor & rac
      , component::IKVStore::flags_t flags
      , std::size_t expected_obj_count
    ) -> std::unique_ptr<Pool> = 0;

    virtual auto pool_open_1(
      const pool_path &path_
    ) -> nupm::region_descriptor = 0;

    virtual auto pool_open_2(
      AK_FORMAL
      const nupm::region_descriptor & access_
      , component::IKVStore::flags_t flags_
    ) -> std::unique_ptr<Pool> = 0;

    virtual void pool_delete(const pool_path &path) = 0;
    virtual const std::unique_ptr<dax_manager> & get_dax_manager() const = 0;
  };

#endif

max_stars_repo_name: fQuinzan/mcas

max_issues_repo_name: fQuinzan/mcas

max_forks_repo_name: fQuinzan/mcas


text:
/* gaussiate - generate with the GSL some Gaussian random variates */

#include <err.h>
#include <fcntl.h>
#include <float.h>
#include <getopt.h>
#include <limits.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>

#include <gsl/gsl_randist.h>
#include <gsl/gsl_rng.h>

// https://github.com/thrig/goptfoo
#include <goptfoo.h>

#define DEFAULT_COUNT 10000UL
#define DEFAULT_SIGMA 1.0

unsigned long Flag_Count;       /* -n */
float Flag_Sigma;               /* -S */

void emit_help(void);

int main(int argc, char *argv[])
{
    int ch;
#ifndef __OpenBSD__
    int fd;
#endif
    gsl_rng *gsl_rand;
    uint32_t seed;

#ifdef __OpenBSD__
    if (pledge("stdio", NULL) == -1)
        err(1, "pledge failed");
#endif

    if (!(gsl_rand = gsl_rng_alloc(gsl_rng_taus2)))
        err(EX_SOFTWARE, "could not gsl_rng_alloc()");

#ifdef __OpenBSD__
    seed = arc4random();
#else
    /* assume there is a random device otherwise */
    if ((fd = open("/dev/urandom", O_RDONLY)) == -1)
        err(EX_OSERR, "could not open /dev/urandom");
    if (read(fd, &seed, sizeof(seed)) != sizeof(seed))
        err(EX_OSERR, "incomplete read of /dev/urandom");
    close(fd);
#endif

    while ((ch = getopt(argc, argv, "h?n:S:")) != -1) {
        switch (ch) {
        case 'n':
            Flag_Count = flagtoul(ch, optarg, 1UL, ULONG_MAX);
            break;
        case 'S':
            Flag_Sigma = (float) flagtod(ch, optarg, 0.0, (double) FLT_MAX);
            break;
        case 'h':
        case '?':
        default:
            emit_help();
            /* NOTREACHED */
        }
    }
    argc -= optind;
    argv += optind;

    if (Flag_Count == 0)
        Flag_Count = DEFAULT_COUNT;

    if (!isnormal(Flag_Sigma))
        Flag_Sigma = DEFAULT_SIGMA;

    gsl_rng_set(gsl_rand, seed);

    for (unsigned long n = 0; n < Flag_Count; n++)
        printf("%.6f\n", gsl_ran_gaussian(gsl_rand, Flag_Sigma));

    exit(EXIT_SUCCESS);
}

void emit_help(void)
{
    fputs("Usage: gaussiate [-n count] [-S sigma]\n", stderr);
    exit(EX_USAGE);
}

max_stars_repo_name: thrig/scripts

max_issues_repo_name: thrig/scripts

max_forks_repo_name: thrig/scripts