<commit_before>#ifndef LIBICS3_ICS3_EEPPARAM_H_
#define LIBICS3_ICS3_EEPPARAM_H_

#include"ics3/check_invalid.hpp"
#include"ics3/baudrate.hpp"

#include<array>

namespace ics {
  class EepParam {
  public:
    using type = uint16_t;
    using size_type = std::size_t;
    enum Flag : type {
      REVERSE =   0x01,
      FREE =      0x02,
      PWMINH =    0x08,
      ROLL_MODE = 0x10,
      SLAVE =     0x80
    };
    static constexpr int byteSize {4};
    static constexpr type mask {0xF};

    static constexpr EepParam stretch(type = 60);
    static constexpr EepParam speed(type = 127);
    static constexpr EepParam punch(type = 1);
    static constexpr EepParam deadBand(type = 2);
    static constexpr EepParam dumping(type = 40);
    static constexpr EepParam selfTimer(type = 250);
    static constexpr EepParam flag(type = 0x8C);
    static constexpr EepParam pulseMax(type = 11500);
    static constexpr EepParam pulseMin(type = 3500);
    static constexpr EepParam baudrate(type = 10);
    static constexpr EepParam temperature(type = 80);
    static constexpr EepParam current(type = 63);
    static constexpr EepParam response(type = 0);
    static constexpr EepParam userOffset(type = 0);
    static constexpr EepParam id(type = 0);
    static constexpr EepParam strech1(type = 60);
    static constexpr EepParam strech2(type = 60);
    static constexpr EepParam strech3(type = 60);
    static constexpr EepParam newEepParam(const EepParam&, type);

    constexpr type get() const noexcept;
    constexpr operator type() const noexcept;
    void set(type);
    EepParam& operator=(type);
    void write(std::array<uint8_t, 64>&) const noexcept;
    void read(const std::array<uint8_t, 64>&);
  private:
    constexpr explicit EepParam(
        size_type,
        size_type,
        type,
        type,
        type (*)(type, type, type),
        type);
    static constexpr type checkInvalidRange(type, type, type);
    static constexpr type checkInvalidEvenRange(type, type, type);
    static constexpr type checkInvalidFlag(type, type, type);
    static constexpr type checkInvalidBaudrate(type, type, type);
    static constexpr type checkInvalidOffset(type, type, type);

    const size_type offset;
    const size_type length;
    const type min;
    const type max;
    type (*const setFunc)(type, type, type);
    type data;
  };

  constexpr EepParam EepParam::stretch(type data) {
    return EepParam {2, 2, 2, 254, &EepParam::checkInvalidEvenRange, data};
  }

  constexpr EepParam EepParam::speed(type data) {
    return EepParam {4, 2, 1, 127, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::punch(type data) {
    return EepParam {6, 2, 0, 10, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::deadBand(type data) {
    return EepParam {8, 2, 0, 5, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::dumping(type data) {
    return EepParam {10, 2, 1, 255, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::selfTimer(type data) {
    return EepParam {12, 2, 10, 255, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::flag(type data) {
    return EepParam {14, 2, 0, 255, &EepParam::checkInvalidFlag, data};
  }

  constexpr EepParam EepParam::pulseMax(type data) {
    return EepParam {16, 4, 3500, 11500, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::pulseMin(type data) {
    return EepParam {20, 4, 3500, 11500, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::baudrate(type data) {
    return EepParam {26, 2, 0, 10, &EepParam::checkInvalidBaudrate, data};
  }

  constexpr EepParam EepParam::temperature(type data) {
    return EepParam {28, 2, 1, 127, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::current(type data) {
    return EepParam {30, 2, 1, 63, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::response(type data) {
    return EepParam {50, 2, 1, 5, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::userOffset(type data) {
    return EepParam {52, 2, 0x81, 127, &EepParam::checkInvalidOffset, data}; // 0x81 is -127 on uint8_t type
  }

  constexpr EepParam EepParam::id(type data) {
    return EepParam {56, 2, 0, 31, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::strech1(type data) {
    return EepParam {58, 2, 2, 254, &EepParam::checkInvalidEvenRange, data};
  }

  constexpr EepParam EepParam::strech2(type data) {
    return EepParam {60, 2, 2, 254, &EepParam::checkInvalidEvenRange, data};
  }

  constexpr EepParam EepParam::strech3(type data) {
    return EepParam {62, 2, 2, 254, &EepParam::checkInvalidEvenRange, data};
  }

  constexpr EepParam EepParam::newEepParam(const EepParam& paramType, type data) {
    return EepParam {paramType.offset, paramType.length, paramType.min, paramType.max, paramType.setFunc, data};
  }

  constexpr EepParam::type EepParam::get() const noexcept {
    return data;
  }

  constexpr EepParam::operator type() const noexcept {
    return get();
  }

  inline void EepParam::set(type input) {
    data = (*setFunc)(input, min, max); // throw std::invalid_argument, std::out_of_range
  }

  inline EepParam& EepParam::operator=(type input) {
    set(input);
    return *this;
  }

  inline void EepParam::write(std::array<uint8_t, 64>& dest) const noexcept {
    type nowData {data};
    for (size_type i {offset + length - 1}; i >= offset; --i) {
      dest[i] = nowData & mask;
      nowData >>= byteSize;
    }
  }

  inline void EepParam::read(const std::array<uint8_t, 64>& src) {
    type result {0};
    const size_type loopend = offset + length;
    for (size_type i {offset}; i < loopend; ++i) {
      result <<= byteSize;
      result |= src[i] & mask;
    }
    set(result); // throw std::invalid_argument, std::out_of_range
  }
  constexpr EepParam::EepParam(
      size_type offset,
      size_type length,
      type min,
      type max,
      type (*setFunc)(type, type, type),
      type data)
  : offset(offset),
    length(length),
    min(min),
    max(max),
    setFunc(setFunc),
    data(setFunc(data, min, max)) // throw std::invalid_argument, std::out_of_range
  {}

  constexpr EepParam::type EepParam::checkInvalidRange(type input, type min, type max) {
    return ics::checkInvalidRange(input, min, max);
  }

  constexpr EepParam::type EepParam::checkInvalidEvenRange(type input, type min, type max) {
    return input % 2 ?
           throw std::out_of_range {"Must even value"} :
           checkInvalidRange(input, min, max); // throw std::out_of_range
  }

  constexpr EepParam::type EepParam::checkInvalidFlag(type input, type, type) {
    return !(input & 0x04) ? throw std::invalid_argument {"Eepparam(flag): Must up bits 0x04"} :
           ~(input | ~0x60) ? throw std::invalid_argument {"Eepparam(flag): Must down bits 0x60"} :
           input;
  }

  constexpr EepParam::type EepParam::checkInvalidBaudrate(type input, type, type) {
    return input == Baudrate::RATE115200().get() ? input :
           //input == Baudrate::RATE625000().get() ? input :
           //input == Baudrate::RATE1250000().get() ? input :
           throw std::invalid_argument {"baudrate not exist"};
  }

  constexpr EepParam::type EepParam::checkInvalidOffset(type input, type min, type max) {
    return input < max ? input : // this min < 0; min value is 0
           min < input ? input : // this min < 0; input must is bigger than min.
           throw std::out_of_range {"Eeprom(offset): range over"}; // min < input < max is failed
  }
}

#endif // LIBICS3_ICS3_EEPPARAM_H_
<commit_msg>Omit explicit<commit_after>#ifndef LIBICS3_ICS3_EEPPARAM_H_
#define LIBICS3_ICS3_EEPPARAM_H_

#include"ics3/check_invalid.hpp"
#include"ics3/baudrate.hpp"

#include<array>

namespace ics {
  class EepParam {
  public:
    using type = uint16_t;
    using size_type = std::size_t;
    enum Flag : type {
      REVERSE =   0x01,
      FREE =      0x02,
      PWMINH =    0x08,
      ROLL_MODE = 0x10,
      SLAVE =     0x80
    };
    static constexpr int byteSize {4};
    static constexpr type mask {0xF};

    static constexpr EepParam stretch(type = 60);
    static constexpr EepParam speed(type = 127);
    static constexpr EepParam punch(type = 1);
    static constexpr EepParam deadBand(type = 2);
    static constexpr EepParam dumping(type = 40);
    static constexpr EepParam selfTimer(type = 250);
    static constexpr EepParam flag(type = 0x8C);
    static constexpr EepParam pulseMax(type = 11500);
    static constexpr EepParam pulseMin(type = 3500);
    static constexpr EepParam baudrate(type = 10);
    static constexpr EepParam temperature(type = 80);
    static constexpr EepParam current(type = 63);
    static constexpr EepParam response(type = 0);
    static constexpr EepParam userOffset(type = 0);
    static constexpr EepParam id(type = 0);
    static constexpr EepParam strech1(type = 60);
    static constexpr EepParam strech2(type = 60);
    static constexpr EepParam strech3(type = 60);
    static constexpr EepParam newEepParam(const EepParam&, type);

    constexpr type get() const noexcept;
    constexpr operator type() const noexcept;
    void set(type);
    EepParam& operator=(type);
    void write(std::array<uint8_t, 64>&) const noexcept;
    void read(const std::array<uint8_t, 64>&);
  private:
    constexpr EepParam( // non explicit, user cannot touch this
        size_type,
        size_type,
        type,
        type,
        type (*)(type, type, type),
        type);
    static constexpr type checkInvalidRange(type, type, type);
    static constexpr type checkInvalidEvenRange(type, type, type);
    static constexpr type checkInvalidFlag(type, type, type);
    static constexpr type checkInvalidBaudrate(type, type, type);
    static constexpr type checkInvalidOffset(type, type, type);

    const size_type offset;
    const size_type length;
    const type min;
    const type max;
    type (*const setFunc)(type, type, type);
    type data;
  };

  constexpr EepParam EepParam::stretch(type data) {
    return EepParam {2, 2, 2, 254, &EepParam::checkInvalidEvenRange, data};
  }

  constexpr EepParam EepParam::speed(type data) {
    return EepParam {4, 2, 1, 127, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::punch(type data) {
    return EepParam {6, 2, 0, 10, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::deadBand(type data) {
    return EepParam {8, 2, 0, 5, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::dumping(type data) {
    return EepParam {10, 2, 1, 255, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::selfTimer(type data) {
    return EepParam {12, 2, 10, 255, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::flag(type data) {
    return EepParam {14, 2, 0, 255, &EepParam::checkInvalidFlag, data};
  }

  constexpr EepParam EepParam::pulseMax(type data) {
    return EepParam {16, 4, 3500, 11500, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::pulseMin(type data) {
    return EepParam {20, 4, 3500, 11500, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::baudrate(type data) {
    return EepParam {26, 2, 0, 10, &EepParam::checkInvalidBaudrate, data};
  }

  constexpr EepParam EepParam::temperature(type data) {
    return EepParam {28, 2, 1, 127, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::current(type data) {
    return EepParam {30, 2, 1, 63, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::response(type data) {
    return EepParam {50, 2, 1, 5, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::userOffset(type data) {
    return EepParam {52, 2, 0x81, 127, &EepParam::checkInvalidOffset, data}; // 0x81 is -127 on uint8_t type
  }

  constexpr EepParam EepParam::id(type data) {
    return EepParam {56, 2, 0, 31, &EepParam::checkInvalidRange, data};
  }

  constexpr EepParam EepParam::strech1(type data) {
    return EepParam {58, 2, 2, 254, &EepParam::checkInvalidEvenRange, data};
  }

  constexpr EepParam EepParam::strech2(type data) {
    return EepParam {60, 2, 2, 254, &EepParam::checkInvalidEvenRange, data};
  }

  constexpr EepParam EepParam::strech3(type data) {
    return EepParam {62, 2, 2, 254, &EepParam::checkInvalidEvenRange, data};
  }

  constexpr EepParam EepParam::newEepParam(const EepParam& paramType, type data) {
    return EepParam {paramType.offset, paramType.length, paramType.min, paramType.max, paramType.setFunc, data};
  }

  constexpr EepParam::type EepParam::get() const noexcept {
    return data;
  }

  constexpr EepParam::operator type() const noexcept {
    return get();
  }

  inline void EepParam::set(type input) {
    data = (*setFunc)(input, min, max); // throw std::invalid_argument, std::out_of_range
  }

  inline EepParam& EepParam::operator=(type input) {
    set(input);
    return *this;
  }

  inline void EepParam::write(std::array<uint8_t, 64>& dest) const noexcept {
    type nowData {data};
    for (size_type i {offset + length - 1}; i >= offset; --i) {
      dest[i] = nowData & mask;
      nowData >>= byteSize;
    }
  }

  inline void EepParam::read(const std::array<uint8_t, 64>& src) {
    type result {0};
    const size_type loopend = offset + length;
    for (size_type i {offset}; i < loopend; ++i) {
      result <<= byteSize;
      result |= src[i] & mask;
    }
    set(result); // throw std::invalid_argument, std::out_of_range
  }
  constexpr EepParam::EepParam(
      size_type offset,
      size_type length,
      type min,
      type max,
      type (*setFunc)(type, type, type),
      type data)
  : offset(offset),
    length(length),
    min(min),
    max(max),
    setFunc(setFunc),
    data(setFunc(data, min, max)) // throw std::invalid_argument, std::out_of_range
  {}

  constexpr EepParam::type EepParam::checkInvalidRange(type input, type min, type max) {
    return ics::checkInvalidRange(input, min, max);
  }

  constexpr EepParam::type EepParam::checkInvalidEvenRange(type input, type min, type max) {
    return input % 2 ?
           throw std::out_of_range {"Must even value"} :
           checkInvalidRange(input, min, max); // throw std::out_of_range
  }

  constexpr EepParam::type EepParam::checkInvalidFlag(type input, type, type) {
    return !(input & 0x04) ? throw std::invalid_argument {"Eepparam(flag): Must up bits 0x04"} :
           ~(input | ~0x60) ? throw std::invalid_argument {"Eepparam(flag): Must down bits 0x60"} :
           input;
  }

  constexpr EepParam::type EepParam::checkInvalidBaudrate(type input, type, type) {
    return input == Baudrate::RATE115200().get() ? input :
           //input == Baudrate::RATE625000().get() ? input :
           //input == Baudrate::RATE1250000().get() ? input :
           throw std::invalid_argument {"baudrate not exist"};
  }

  constexpr EepParam::type EepParam::checkInvalidOffset(type input, type min, type max) {
    return input < max ? input : // this min < 0; min value is 0
           min < input ? input : // this min < 0; input must is bigger than min.
           throw std::out_of_range {"Eeprom(offset): range over"}; // min < input < max is failed
  }
}

#endif // LIBICS3_ICS3_EEPPARAM_H_
<|endoftext|>


<commit_before>/****************************************************************************
 **
 ** Copyright (C) Qxt Foundation. Some rights reserved.
 **
 ** This file is part of the QxtNetwork module of the Qxt library.
 **
 ** This library is free software; you can redistribute it and/or modify it
 ** under the terms of the Common Public License, version 1.0, as published by
 ** IBM.
 **
 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
 ** FITNESS FOR A PARTICULAR PURPOSE.
 **
 ** You should have received a copy of the CPL along with this file.
 ** See the LICENSE file and the cpl1.0.txt file included with the source
 ** distribution for more information. If you did not receive a copy of the
 ** license, contact the Qxt Foundation.
 **
 ** <http://libqxt.org>  <foundation@libqxt.org>
 **
 ****************************************************************************/

#include <qxtdatastreamsignalserializer.h>
#include <QIODevice>
#include <QDataStream>
#include <QtGlobal>
#include <qendian.h>

QByteArray QxtDataStreamSignalSerializer::serialize(const QString& fn, const QVariant& p1, const QVariant& p2, const QVariant& p3,
                               const QVariant& p4, const QVariant& p5, const QVariant& p6, const QVariant& p7, const QVariant& p8) const
{
    QByteArray rv;
    QDataStream str(&rv, QIODevice::WriteOnly);
    str << fn;
    unsigned char ct = 8;
    if (p1.isNull()) ct = 0;
    else if (p2.isNull()) ct = 1;
    else if (p3.isNull()) ct = 2;
    else if (p4.isNull()) ct = 3;
    else if (p5.isNull()) ct = 4;
    else if (p6.isNull()) ct = 5;
    else if (p7.isNull()) ct = 6;
    else if (p8.isNull()) ct = 7;
    str << ct;
    if (ct-- > 0) str << p1;
    if (ct-- > 0) str << p2;
    if (ct-- > 0) str << p3;
    if (ct-- > 0) str << p4;
    if (ct-- > 0) str << p5;
    if (ct-- > 0) str << p6;
    if (ct-- > 0) str << p7;
    if (ct-- > 0) str << p8;
	uchar sizeData[4];
    qToLittleEndian(rv.size(), sizeData);
    return rv;
}

QxtAbstractSignalSerializer::DeserializedData QxtDataStreamSignalSerializer::deserialize(QByteArray& data)
{
    QByteArray cmd;
    int pos = data.indexOf('\n');

    cmd = data.left(pos);
    data = data.mid(pos+1);
    if (cmd.length()==0) return NoOp();

    cmd.replace(QByteArray("\\n"), QByteArray("\n"));
    cmd.replace(QByteArray("\\\\"), QByteArray("\\"));
    QDataStream str(cmd);

    QString signal;
    unsigned char argCount;
    QList<QVariant> v;
    QVariant t;
    str >> signal >> argCount;

    if(str.status() == QDataStream::ReadCorruptData) return ProtocolError();

    for (int i=0; i<argCount; i++)
    {
        str >> t;
        v << t;
    }
    return qMakePair(signal, v);
}

bool QxtDataStreamSignalSerializer::canDeserialize(const QByteArray& buffer) const {
    return buffer.indexOf('\n') != -1;
}
<commit_msg>fix message framing<commit_after>/****************************************************************************
 **
 ** Copyright (C) Qxt Foundation. Some rights reserved.
 **
 ** This file is part of the QxtNetwork module of the Qxt library.
 **
 ** This library is free software; you can redistribute it and/or modify it
 ** under the terms of the Common Public License, version 1.0, as published by
 ** IBM.
 **
 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
 ** FITNESS FOR A PARTICULAR PURPOSE.
 **
 ** You should have received a copy of the CPL along with this file.
 ** See the LICENSE file and the cpl1.0.txt file included with the source
 ** distribution for more information. If you did not receive a copy of the
 ** license, contact the Qxt Foundation.
 **
 ** <http://libqxt.org>  <foundation@libqxt.org>
 **
 ****************************************************************************/

#include <qxtdatastreamsignalserializer.h>
#include <QIODevice>
#include <QDataStream>
#include <QtGlobal>
#include <qendian.h>

QByteArray QxtDataStreamSignalSerializer::serialize(const QString& fn, const QVariant& p1, const QVariant& p2, const QVariant& p3,
                               const QVariant& p4, const QVariant& p5, const QVariant& p6, const QVariant& p7, const QVariant& p8) const
{
    QByteArray rv;
    QDataStream str(&rv, QIODevice::WriteOnly);
    str << fn;
    unsigned char ct = 8;
    if (p1.isNull()) ct = 0;
    else if (p2.isNull()) ct = 1;
    else if (p3.isNull()) ct = 2;
    else if (p4.isNull()) ct = 3;
    else if (p5.isNull()) ct = 4;
    else if (p6.isNull()) ct = 5;
    else if (p7.isNull()) ct = 6;
    else if (p8.isNull()) ct = 7;
    str << ct;
    if (ct-- > 0) str << p1;
    if (ct-- > 0) str << p2;
    if (ct-- > 0) str << p3;
    if (ct-- > 0) str << p4;
    if (ct-- > 0) str << p5;
    if (ct-- > 0) str << p6;
    if (ct-- > 0) str << p7;
    if (ct-- > 0) str << p8;
	uchar sizeData[4];
    qToLittleEndian(quint32(rv.size()), sizeData);
    return rv;
}

QxtAbstractSignalSerializer::DeserializedData QxtDataStreamSignalSerializer::deserialize(QByteArray& data)
{
    QByteArray cmd;
    quint32 len = qFromLittleEndian<quint32>(buffer.constData());

    cmd = data.mid(4,pos);
    data = data.mid(pos+4);
    if (cmd.length()==0) return NoOp();

    QDataStream str(cmd);

    QString signal;
    unsigned char argCount;
    QList<QVariant> v;
    QVariant t;
    str >> signal >> argCount;

    if(str.status() == QDataStream::ReadCorruptData) return ProtocolError();

    for (int i=0; i<argCount; i++)
    {
        str >> t;
        v << t;
    }
    return qMakePair(signal, v);
}

bool QxtDataStreamSignalSerializer::canDeserialize(const QByteArray& buffer) const {
    return qFromLittleEndian<quint32>(buffer.constData()) >= (buffer.length() - 4);
}
<|endoftext|>


<commit_before>#include "link.h"

bool Link::Prescreening_Sort_(BasisShell* shellA, BasisShell* shellB) {

  return ((shellA->max_schwartz_factor() * shellA->current_density_entry()) <
          (shellB->max_schwartz_factor() * shellB->current_density_entry()));

}

bool Link::ShellPairSort_(ShellPair* shellA, ShellPair* shellB) {

  return(shellA->schwartz_factor() < shellB->schwartz_factor());

}

void Link::PrescreeningLoop_() {

  // Find "significant" bra and ket shell pairs
  // These need to be ordered in terms of their Schwartz estimates
  // I think shell_pair_list_ needs to be a list of lists
  // One list of shell pairs for each mu
  num_shell_pairs_ = eri::ComputeShellPairs(&shell_pair_list_, shell_list_,
                                            shell_pair_cutoff_, &shell_max_,
                                            significant_sigma_for_nu_,
                                            &num_significant_sigma_for_nu_);

  fx_result_int(module_, "num_shell_pairs", num_shell_pairs_);
  fx_result_int(module_, "num_shell_pairs_screened",
                num_shells_ * (num_shells_ - 1) / 2);

  //// Find significant \nu for all \mu

  // I am supposed to loop over all mu in significant bra shell pairs and over
  // all nu in significant ket shell pairs
  // Maybe I should just loop over the shells themselves and assume that each
  // shell appears in at least one significant shell pair
  for (index_t i = 0; i < num_shells_; i++) {

    current_mu_ = i;

    index_t next_ind = 0;

    ArrayList<index_t> significant_nu_index;
    significant_nu_index.Init(num_shells_);

    for (index_t j = 0; j < num_shells_; j++) {

      // I think this threshold should be the same as the others
      // Not sure if this is the right density matrix entry
      if (density_matrix_.ref(i,j) * shell_max_[i] * shell_max_[j] > threshold_) {

        // Store significant j for each i
        // What is the best way to do this?  This list will have to be sorted
        // This fails if there are more than num_shells_/2 significant elements
        significant_nu_index[next_ind] = j;

        // I need to store next_ind somehow in order to be able to iterate
        // later
        next_ind++;

      }

    } // for j

    num_significant_nu_for_mu_[i] = next_ind;

    significant_nu_for_mu_[i] = (BasisShell**)malloc(next_ind *
                                                    sizeof(BasisShell**));
    //BasisShell** significant_mu_pairs_[i] = significant_mu_pairs_[i];

    for (index_t k = 0; k < next_ind; k++) {

      significant_nu_for_mu_[i][k] = shell_list_.begin() +
      significant_nu_index[k];
      significant_nu_for_mu_[i][k]->set_max_schwartz_factor(shell_max_[k]);
      significant_nu_for_mu_[i][k]->set_current_density_entry(density_matrix_.ref(i,k));

    } // for k

    // sort significant_nu_for_mu

    std::sort(significant_nu_for_mu_[i], significant_nu_for_mu_[i]+next_ind,
              Link::Prescreening_Sort_);

    /*
    for (index_t a = 0; a < next_ind; a++) {
      printf("sort_val: %g\n",
             significant_nu_for_mu_[i][a]->max_schwartz_factor() *
             significant_nu_for_mu_[i][a]->current_density_entry());

    }
    */

    // sort significant_sigma_for_nu_[i] for all i
    // should I do this here?
    std::sort(significant_sigma_for_nu_[i],
              significant_sigma_for_nu_[i]+num_significant_sigma_for_nu_[i],
              Link::ShellPairSort_);

  } // for i

}

void Link::ComputeExchangeMatrix() {

  fx_timer_start(module_, "LinK_time");

  // Prescreening loop
  printf("====LinK Prescreening====\n");
  fx_timer_start(module_, "prescreening");
  PrescreeningLoop_();
  fx_timer_stop(module_, "prescreening");

  printf("====LinK Screening and Computing Integrals====\n");
  fx_timer_start(module_, "integrals");
  // loop over bra shell pairs

  for (index_t shell_pair_ind = 0; shell_pair_ind < num_shell_pairs_;
       shell_pair_ind++) {

    ShellPair mu_lambda = shell_pair_list_[shell_pair_ind];

    index_t mu_ind = mu_lambda.M_index();

    index_t lambda_ind = mu_lambda.N_index();

    index_t num_mu_integrals = 0;
    index_t num_lambda_integrals = 0;
    ArrayList<index_t> mu_integrals;
    ArrayList<index_t> lambda_integrals;

    mu_integrals.Init();
    lambda_integrals.Init();

    // loop over nu corresponding to mu
    // what is num_nu?
    index_t num_nu = num_significant_nu_for_mu_[mu_ind];
    for (index_t sorted_nu_ind = 0; sorted_nu_ind < num_nu; sorted_nu_ind++) {

      index_t significant_sigmas = 0;

      // need to get this from the first sorted list
      BasisShell* nu_shell = significant_nu_for_mu_[mu_ind][sorted_nu_ind];
      // not sure this will be right for higher momenta
      index_t nu_ind = nu_shell->start_index();

      index_t num_sigma = num_significant_sigma_for_nu_[nu_ind];

      for (index_t sorted_sigma_ind = 0; sorted_sigma_ind < num_sigma;
           sorted_sigma_ind++) {

        ShellPair* nu_sigma = significant_sigma_for_nu_[nu_ind][sorted_sigma_ind];

        //index_t sigma_ind = nu_sigma->N_index();
        double bound = fabs(density_matrix_.ref(mu_ind, nu_ind)) * mu_lambda.schwartz_factor() *
          nu_sigma->schwartz_factor();
        if (bound > threshold_) {

          // store or compute the eri
          // need to change this to storing it so I can merge the lists later
          // create a list of index_t, list[i] = j, where shell_pairs_[j] has
          // significant integrals relative to mu_lambda
          // this list will need to be sorted, then I can use std::set_union

          // how am I going to get the index of nu_sigma in the list of shell
          // pairs?
          mu_integrals.PushBack();
          mu_integrals[num_mu_integrals] = nu_sigma->list_index();
          num_mu_integrals++;

          significant_sigmas++;

        }
        // leave sigma loop, since it is sorted
        else {
          //printf("left sigma loop, bound: %g\n", bound);
          num_neglected_sigma_ += num_sigma - sorted_sigma_ind - 1;
          break;
        }

      } // for sigma_ind

      // exit loop if this nu has no sigmas that count
      if (significant_sigmas == 0) {
        //printf("left nu loop\n");
        num_neglected_nu_ += num_nu - sorted_nu_ind - 1;
        break;
      }

    } // for nu_ind

    // loop over nu corresponding to lambda and do same
    // why is this necessary as well?
    // I think it's important for the symmetry, lambda mu never shows up as a
    // shell pair
    // shouldn't do this if lambda == mu

    // currently assumes that there is at least one significant integral for
    // for this shell pair - this needs to be fixed

    if (mu_ind != lambda_ind) {
      //printf("lambda loop\n");
      num_nu = num_significant_nu_for_mu_[lambda_ind];

      for (index_t sorted_nu_ind = 0; sorted_nu_ind < num_nu; sorted_nu_ind++) {

        index_t significant_sigmas = 0;

        // need to get this from the first sorted list
        BasisShell* nu_shell = significant_nu_for_mu_[mu_ind][sorted_nu_ind];
        // not sure this will be right for higher momenta
        index_t nu_ind = nu_shell->start_index();

        index_t num_sigma = num_significant_sigma_for_nu_[nu_ind];

        for (index_t sorted_sigma_ind = 0; sorted_sigma_ind < num_sigma;
             sorted_sigma_ind++) {

          ShellPair* nu_sigma = significant_sigma_for_nu_[nu_ind][sorted_sigma_ind];

          //index_t sigma_ind = nu_sigma->N_index();

          if (fabs(density_matrix_.ref(mu_ind, nu_ind)) * mu_lambda.schwartz_factor() *
              nu_sigma->schwartz_factor() > threshold_) {

            lambda_integrals.PushBack();
            //printf("list_index: %d\n", nu_sigma->list_index());
            lambda_integrals[num_lambda_integrals] = nu_sigma->list_index();
            num_lambda_integrals++;

            significant_sigmas++;

          }
          // leave sigma loop, since it is sorted
          else {
            //printf("left sigma loop\n");
            num_neglected_sigma_ += num_sigma - sorted_sigma_ind - 1;
            break;
          }

        } // for sigma_ind

        // exit loop if this nu has no sigmas that count
        if (significant_sigmas == 0) {
          //printf("left nu loop\n");
          num_neglected_nu_ += num_nu - sorted_nu_ind - 1;
          break;
        }

      } // for nu_ind

    } // if lambda != mu
    else {

      // make the list non-void for the union step below
      lambda_integrals.PushBack();
      lambda_integrals[num_lambda_integrals] = mu_integrals[0];
      num_lambda_integrals++;

    }

    // compute significant integrals
    // may just do this inside loop

    // sort before calling union
    std::sort(mu_integrals.begin(), mu_integrals.begin()+num_mu_integrals);
    std::sort(lambda_integrals.begin(),
              lambda_integrals.begin() + num_lambda_integrals);

    index_t* end_integrals;
    ArrayList<index_t> integral_list;
    integral_list.Init(num_shell_pairs_);

    end_integrals = std::set_union(mu_integrals.begin(),
                                   mu_integrals.begin()+num_mu_integrals,
                                   lambda_integrals.begin(),
                                   lambda_integrals.begin() + num_lambda_integrals,
                                   integral_list.begin());

    index_t num_integrals = end_integrals - integral_list.begin();
    //printf("num_integrals = %d\n", num_integrals);

    // compute the integrals

    for (index_t int_ind = 0; int_ind < num_integrals; int_ind++) {

      ShellPair nu_sigma = shell_pair_list_[integral_list[int_ind]];

      index_t nu_ind = nu_sigma.M_index();
      index_t sigma_ind = nu_sigma.N_index();
      //printf("mu_ind: %d, nu_ind: %d, lambda_ind: %d, sigma_ind: %d\n", mu_ind,
        //     nu_ind, lambda_ind, sigma_ind);

      double integral = eri::ComputeShellIntegrals(mu_lambda, nu_sigma);
      // contract with mu, nu; mu, sigma; lambda, nu; lambda, sigma
      // sum into lambda, sigma; lambda, nu; mu, sigma; mu, nu

      double mu_nu_int = density_matrix_.ref(mu_ind, nu_ind) * integral;
      double mu_sigma_int = density_matrix_.ref(mu_ind, sigma_ind) * integral;
      double lambda_nu_int = density_matrix_.ref(lambda_ind, nu_ind) * integral;
      double lambda_sigma_int = density_matrix_.ref(lambda_ind, sigma_ind) * integral;

      double mu_nu_exc = exchange_matrix_.ref(mu_ind, nu_ind);
      double mu_sigma_exc = exchange_matrix_.ref(mu_ind, sigma_ind);
      double lambda_nu_exc = exchange_matrix_.ref(lambda_ind, nu_ind);
      double lambda_sigma_exc = exchange_matrix_.ref(lambda_ind, sigma_ind);

      exchange_matrix_.set(mu_ind, nu_ind, mu_nu_exc + lambda_sigma_int);
      if (sigma_ind != nu_ind) {
        exchange_matrix_.set(mu_ind, sigma_ind,
                             mu_sigma_exc + lambda_nu_int);
      }
      if (lambda_ind != mu_ind){
        exchange_matrix_.set(lambda_ind, nu_ind,
                             lambda_nu_exc + mu_sigma_int);
      }
      if ((lambda_ind != mu_ind) && (nu_ind != sigma_ind)) {
        exchange_matrix_.set(lambda_ind, sigma_ind,
                             lambda_sigma_exc + mu_nu_int);
      }

    } // for int_ind

  } // for bra shell pairs

  fx_timer_stop(module_, "integrals");

  fx_timer_stop(module_, "LinK_time");

} // ComputeExchangeMatrix()

void Link::OutputExchangeMatrix(Matrix* exc_out) {

  fx_result_int(module_, "num_neglected_sigma", num_neglected_sigma_);
  fx_result_int(module_, "num_neglected_nu", num_neglected_nu_);

  la::Scale(0.5, &exchange_matrix_);
  exc_out->Copy(exchange_matrix_);

} // OutputFockMatrix

<commit_msg>fixed num pruned shell pairs<commit_after>#include "link.h"

bool Link::Prescreening_Sort_(BasisShell* shellA, BasisShell* shellB) {

  return ((shellA->max_schwartz_factor() * shellA->current_density_entry()) <
          (shellB->max_schwartz_factor() * shellB->current_density_entry()));

}

bool Link::ShellPairSort_(ShellPair* shellA, ShellPair* shellB) {

  return(shellA->schwartz_factor() < shellB->schwartz_factor());

}

void Link::PrescreeningLoop_() {

  // Find "significant" bra and ket shell pairs
  // These need to be ordered in terms of their Schwartz estimates
  // I think shell_pair_list_ needs to be a list of lists
  // One list of shell pairs for each mu
  num_shell_pairs_ = eri::ComputeShellPairs(&shell_pair_list_, shell_list_,
                                            shell_pair_cutoff_, &shell_max_,
                                            significant_sigma_for_nu_,
                                            &num_significant_sigma_for_nu_);

  fx_result_int(module_, "num_shell_pairs", num_shell_pairs_);
  fx_result_int(module_, "num_shell_pairs_screened",
                num_shell_pairs_ - (num_shells_ * (num_shells_ - 1) / 2) - num_shells_);

  //// Find significant \nu for all \mu

  // I am supposed to loop over all mu in significant bra shell pairs and over
  // all nu in significant ket shell pairs
  // Maybe I should just loop over the shells themselves and assume that each
  // shell appears in at least one significant shell pair
  for (index_t i = 0; i < num_shells_; i++) {

    current_mu_ = i;

    index_t next_ind = 0;

    ArrayList<index_t> significant_nu_index;
    significant_nu_index.Init(num_shells_);

    for (index_t j = 0; j < num_shells_; j++) {

      // I think this threshold should be the same as the others
      // Not sure if this is the right density matrix entry
      if (density_matrix_.ref(i,j) * shell_max_[i] * shell_max_[j] > threshold_) {

        // Store significant j for each i
        // What is the best way to do this?  This list will have to be sorted
        // This fails if there are more than num_shells_/2 significant elements
        significant_nu_index[next_ind] = j;

        // I need to store next_ind somehow in order to be able to iterate
        // later
        next_ind++;

      }

    } // for j

    num_significant_nu_for_mu_[i] = next_ind;

    significant_nu_for_mu_[i] = (BasisShell**)malloc(next_ind *
                                                    sizeof(BasisShell**));
    //BasisShell** significant_mu_pairs_[i] = significant_mu_pairs_[i];

    for (index_t k = 0; k < next_ind; k++) {

      significant_nu_for_mu_[i][k] = shell_list_.begin() +
      significant_nu_index[k];
      significant_nu_for_mu_[i][k]->set_max_schwartz_factor(shell_max_[k]);
      significant_nu_for_mu_[i][k]->set_current_density_entry(density_matrix_.ref(i,k));

    } // for k

    // sort significant_nu_for_mu

    std::sort(significant_nu_for_mu_[i], significant_nu_for_mu_[i]+next_ind,
              Link::Prescreening_Sort_);

    /*
    for (index_t a = 0; a < next_ind; a++) {
      printf("sort_val: %g\n",
             significant_nu_for_mu_[i][a]->max_schwartz_factor() *
             significant_nu_for_mu_[i][a]->current_density_entry());

    }
    */

    // sort significant_sigma_for_nu_[i] for all i
    // should I do this here?
    std::sort(significant_sigma_for_nu_[i],
              significant_sigma_for_nu_[i]+num_significant_sigma_for_nu_[i],
              Link::ShellPairSort_);

  } // for i

}

void Link::ComputeExchangeMatrix() {

  fx_timer_start(module_, "LinK_time");

  // Prescreening loop
  printf("====LinK Prescreening====\n");
  fx_timer_start(module_, "prescreening");
  PrescreeningLoop_();
  fx_timer_stop(module_, "prescreening");

  printf("====LinK Screening and Computing Integrals====\n");
  fx_timer_start(module_, "integrals");
  // loop over bra shell pairs

  for (index_t shell_pair_ind = 0; shell_pair_ind < num_shell_pairs_;
       shell_pair_ind++) {

    ShellPair mu_lambda = shell_pair_list_[shell_pair_ind];

    index_t mu_ind = mu_lambda.M_index();

    index_t lambda_ind = mu_lambda.N_index();

    index_t num_mu_integrals = 0;
    index_t num_lambda_integrals = 0;
    ArrayList<index_t> mu_integrals;
    ArrayList<index_t> lambda_integrals;

    mu_integrals.Init();
    lambda_integrals.Init();

    // loop over nu corresponding to mu
    // what is num_nu?
    index_t num_nu = num_significant_nu_for_mu_[mu_ind];
    for (index_t sorted_nu_ind = 0; sorted_nu_ind < num_nu; sorted_nu_ind++) {

      index_t significant_sigmas = 0;

      // need to get this from the first sorted list
      BasisShell* nu_shell = significant_nu_for_mu_[mu_ind][sorted_nu_ind];
      // not sure this will be right for higher momenta
      index_t nu_ind = nu_shell->start_index();

      index_t num_sigma = num_significant_sigma_for_nu_[nu_ind];

      for (index_t sorted_sigma_ind = 0; sorted_sigma_ind < num_sigma;
           sorted_sigma_ind++) {

        ShellPair* nu_sigma = significant_sigma_for_nu_[nu_ind][sorted_sigma_ind];

        //index_t sigma_ind = nu_sigma->N_index();
        double bound = fabs(density_matrix_.ref(mu_ind, nu_ind)) * mu_lambda.schwartz_factor() *
          nu_sigma->schwartz_factor();
        if (bound > threshold_) {

          // store or compute the eri
          // need to change this to storing it so I can merge the lists later
          // create a list of index_t, list[i] = j, where shell_pairs_[j] has
          // significant integrals relative to mu_lambda
          // this list will need to be sorted, then I can use std::set_union

          // how am I going to get the index of nu_sigma in the list of shell
          // pairs?
          mu_integrals.PushBack();
          mu_integrals[num_mu_integrals] = nu_sigma->list_index();
          num_mu_integrals++;

          significant_sigmas++;

        }
        // leave sigma loop, since it is sorted
        else {
          //printf("left sigma loop, bound: %g\n", bound);
          num_neglected_sigma_ += num_sigma - sorted_sigma_ind - 1;
          break;
        }

      } // for sigma_ind

      // exit loop if this nu has no sigmas that count
      if (significant_sigmas == 0) {
        //printf("left nu loop\n");
        num_neglected_nu_ += num_nu - sorted_nu_ind - 1;
        break;
      }

    } // for nu_ind

    // loop over nu corresponding to lambda and do same
    // why is this necessary as well?
    // I think it's important for the symmetry, lambda mu never shows up as a
    // shell pair
    // shouldn't do this if lambda == mu

    // currently assumes that there is at least one significant integral for
    // for this shell pair - this needs to be fixed

    if (mu_ind != lambda_ind) {
      //printf("lambda loop\n");
      num_nu = num_significant_nu_for_mu_[lambda_ind];

      for (index_t sorted_nu_ind = 0; sorted_nu_ind < num_nu; sorted_nu_ind++) {

        index_t significant_sigmas = 0;

        // need to get this from the first sorted list
        BasisShell* nu_shell = significant_nu_for_mu_[mu_ind][sorted_nu_ind];
        // not sure this will be right for higher momenta
        index_t nu_ind = nu_shell->start_index();

        index_t num_sigma = num_significant_sigma_for_nu_[nu_ind];

        for (index_t sorted_sigma_ind = 0; sorted_sigma_ind < num_sigma;
             sorted_sigma_ind++) {

          ShellPair* nu_sigma = significant_sigma_for_nu_[nu_ind][sorted_sigma_ind];

          //index_t sigma_ind = nu_sigma->N_index();

          if (fabs(density_matrix_.ref(mu_ind, nu_ind)) * mu_lambda.schwartz_factor() *
              nu_sigma->schwartz_factor() > threshold_) {

            lambda_integrals.PushBack();
            //printf("list_index: %d\n", nu_sigma->list_index());
            lambda_integrals[num_lambda_integrals] = nu_sigma->list_index();
            num_lambda_integrals++;

            significant_sigmas++;

          }
          // leave sigma loop, since it is sorted
          else {
            //printf("left sigma loop\n");
            num_neglected_sigma_ += num_sigma - sorted_sigma_ind - 1;
            break;
          }

        } // for sigma_ind

        // exit loop if this nu has no sigmas that count
        if (significant_sigmas == 0) {
          //printf("left nu loop\n");
          num_neglected_nu_ += num_nu - sorted_nu_ind - 1;
          break;
        }

      } // for nu_ind

    } // if lambda != mu
    else {

      // make the list non-void for the union step below
      lambda_integrals.PushBack();
      lambda_integrals[num_lambda_integrals] = mu_integrals[0];
      num_lambda_integrals++;

    }

    // compute significant integrals
    // may just do this inside loop

    // sort before calling union
    std::sort(mu_integrals.begin(), mu_integrals.begin()+num_mu_integrals);
    std::sort(lambda_integrals.begin(),
              lambda_integrals.begin() + num_lambda_integrals);

    index_t* end_integrals;
    ArrayList<index_t> integral_list;
    integral_list.Init(num_shell_pairs_);

    end_integrals = std::set_union(mu_integrals.begin(),
                                   mu_integrals.begin()+num_mu_integrals,
                                   lambda_integrals.begin(),
                                   lambda_integrals.begin() + num_lambda_integrals,
                                   integral_list.begin());

    index_t num_integrals = end_integrals - integral_list.begin();
    //printf("num_integrals = %d\n", num_integrals);

    // compute the integrals

    for (index_t int_ind = 0; int_ind < num_integrals; int_ind++) {

      ShellPair nu_sigma = shell_pair_list_[integral_list[int_ind]];

      index_t nu_ind = nu_sigma.M_index();
      index_t sigma_ind = nu_sigma.N_index();
      //printf("mu_ind: %d, nu_ind: %d, lambda_ind: %d, sigma_ind: %d\n", mu_ind,
        //     nu_ind, lambda_ind, sigma_ind);

      double integral = eri::ComputeShellIntegrals(mu_lambda, nu_sigma);
      // contract with mu, nu; mu, sigma; lambda, nu; lambda, sigma
      // sum into lambda, sigma; lambda, nu; mu, sigma; mu, nu

      double mu_nu_int = density_matrix_.ref(mu_ind, nu_ind) * integral;
      double mu_sigma_int = density_matrix_.ref(mu_ind, sigma_ind) * integral;
      double lambda_nu_int = density_matrix_.ref(lambda_ind, nu_ind) * integral;
      double lambda_sigma_int = density_matrix_.ref(lambda_ind, sigma_ind) * integral;

      double mu_nu_exc = exchange_matrix_.ref(mu_ind, nu_ind);
      double mu_sigma_exc = exchange_matrix_.ref(mu_ind, sigma_ind);
      double lambda_nu_exc = exchange_matrix_.ref(lambda_ind, nu_ind);
      double lambda_sigma_exc = exchange_matrix_.ref(lambda_ind, sigma_ind);

      exchange_matrix_.set(mu_ind, nu_ind, mu_nu_exc + lambda_sigma_int);
      if (sigma_ind != nu_ind) {
        exchange_matrix_.set(mu_ind, sigma_ind,
                             mu_sigma_exc + lambda_nu_int);
      }
      if (lambda_ind != mu_ind){
        exchange_matrix_.set(lambda_ind, nu_ind,
                             lambda_nu_exc + mu_sigma_int);
      }
      if ((lambda_ind != mu_ind) && (nu_ind != sigma_ind)) {
        exchange_matrix_.set(lambda_ind, sigma_ind,
                             lambda_sigma_exc + mu_nu_int);
      }

    } // for int_ind

  } // for bra shell pairs

  fx_timer_stop(module_, "integrals");

  fx_timer_stop(module_, "LinK_time");

} // ComputeExchangeMatrix()

void Link::OutputExchangeMatrix(Matrix* exc_out) {

  fx_result_int(module_, "num_neglected_sigma", num_neglected_sigma_);
  fx_result_int(module_, "num_neglected_nu", num_neglected_nu_);

  la::Scale(0.5, &exchange_matrix_);
  exc_out->Copy(exchange_matrix_);

} // OutputFockMatrix

<|endoftext|>


<commit_before>#include <QUrl>
#include "kernel.h"
#include "mastercatalog.h"
#include "connectorinterface.h"
#include "ilwisobjectconnector.h"

using namespace Ilwis;

IlwisObjectConnector::IlwisObjectConnector(const Ilwis::Resource &resource, bool) : _resource(resource)
{
}

IlwisTypes IlwisObjectConnector::type() const
{
    return _resource.ilwisType();
}

Resource &IlwisObjectConnector::source()
{
    return _resource;
}
<commit_msg>integrated containerConnector<commit_after>#include <QUrl>
#include "kernel.h"
#include "mastercatalog.h"
#include "connectorinterface.h"
#include "containerconnector.h"
#include "factory.h"
#include "abstractfactory.h"
#include "connectorfactory.h"
#include "ilwisobjectconnector.h"

using namespace Ilwis;

IlwisObjectConnector::IlwisObjectConnector(const Ilwis::Resource &resource, bool) : _resource(resource)
{
    const ConnectorFactory *factory = kernel()->factory<ConnectorFactory>("ConnectorFactory",resource);

    if ( factory)
         _incontainerconnector.reset(dynamic_cast<ContainerConnector *>(factory->createSuitable(Resource(resource.url(), itCONTAINER))));
    else {
        kernel()->issues()->log(TR("Cann't find suitable factory for %1 ").arg(resource.name()));
    }
}

IlwisTypes IlwisObjectConnector::type() const
{
    return _resource.ilwisType();
}

Resource &IlwisObjectConnector::source()
{
    return _resource;
}

std::unique_ptr<ContainerConnector> &IlwisObjectConnector::containerConnector(IlwisObject::ConnectorMode mode)
{
    if ( mode & IlwisObject::cmINPUT)
        return _incontainerconnector;
    else if ( mode & IlwisObject::cmOUTPUT)
        if ( _outcontainerconnector)
            return _outcontainerconnector;
    return _incontainerconnector;
}

const std::unique_ptr<ContainerConnector> &IlwisObjectConnector::containerConnector(IlwisObject::ConnectorMode mode) const
{
    if ( mode &IlwisObject:: cmINPUT)
        return _incontainerconnector;
    else if ( mode & IlwisObject::cmOUTPUT)
        if ( _outcontainerconnector)
            return _outcontainerconnector;
    return _incontainerconnector;
}
<|endoftext|>


<commit_before>/*
 * ConnectedComponents.cpp
 *
 *  Created on: Dec 16, 2013
 *      Author: cls
 */

#include "ConnectedComponents.h"
#include "../structures/Partition.h"
#include "../coarsening/PartitionCoarsening.h"
#include <set>

namespace NetworKit {

ConnectedComponents::ConnectedComponents() {

}

ConnectedComponents::~ConnectedComponents() {

}

void ConnectedComponents::run(const Graph& G) {
	// calculate connected components by label propagation
	count z = G.numberOfNodes();
	this->component = std::vector<node>(z, none);

	Partition partition(G.upperNodeIdBound());
	partition.allToSingletons();

	DEBUG("initializing labels");
	G.parallelForNodes([&](node v) {
		component[v] = v;
	});

	DEBUG("initializing active nodes");
	std::vector<bool> activeNodes(z); // record if node must be processed
	activeNodes.assign(z, true);
	G.forNodes([&](node u) { // NOTE: not in parallel due to implementation of bit vector
		if (G.degree(u) == 0) {
			activeNodes[u] = false;
		}
	});

	DEBUG("main loop");
	count numActive = 0; // for debugging purposes only
	count numIterations = 0;
	bool change = false;
	do {
//		TRACE("label propagation iteration");
		change = false;
		numActive = 0;
		G.forNodes([&](node u) {
			if (activeNodes[u]) {
				++numActive;
				std::vector<index> neighborLabels;
				G.forNeighborsOf(u, [&](node v) {
					// neighborLabels.push_back(component[v]);
					neighborLabels.push_back(partition[v]);
				});
				// get smallest
				index smallest = *std::min_element(neighborLabels.begin(), neighborLabels.end());

				if (component[u] != smallest) {
					component[u] = smallest;
					partition.moveToSubset(smallest, u);
					change = true;
					G.forNeighborsOf(u, [&](node v) {
						activeNodes[v] = true;
					});
				} else {
					activeNodes[u] = false; // current node becomes inactive
				}
			}
		});
		TRACE("num active: ", numActive);
		++numIterations;
		if ((numIterations % 10) == 0) {
			// coarsen and make recursive call
			PartitionCoarsening con;
			std::pair<Graph, std::vector<node> > coarse = con.run(G, partition);
			ConnectedComponents cc;
			cc.run(coarse.first);

			// apply to current graph
			G.forNodes([&](node u) {
				component[u] = cc.componentOfNode(coarse.second[u]);
				partition[u] = component[u];
			});
		}
	} while (change);
}

std::vector<index> ConnectedComponents::getComponentData() {
	return this->component;
}

std::map<index, count> ConnectedComponents::getComponentSizes() {
	std::map<index, count> componentSize;
	for (node u = 0; u < component.size(); ++u) {
		if (component[u] != none) {
			componentSize[component[u]] += 1;
		}
	}
	return componentSize;
}

std::vector<node> ConnectedComponents::getComponent(index label) {
	std::vector<node> nodesOfComponent;
	for (node u = 0; u < component.size(); ++u) {
		if (this->component[u] == label) {
			nodesOfComponent.push_back(u);
		}
	}
	return nodesOfComponent;
}

count ConnectedComponents::numberOfComponents() {
	count nc = 0;
	std::set<index> componentLabels;
	for (index i = 0; i < component.size(); ++i) {
		index c = component[i];
		if ((componentLabels.find(c) == componentLabels.end()) && (c != none)) { // label not encountered yet
			componentLabels.insert(c);
			nc++;
		}
	}
	return nc;
}

count ConnectedComponents::componentOfNode(node u) {
	assert (component[u] != none);
	return component[u];
}

}

<commit_msg>conn. comp. yet a little faster<commit_after>/*
 * ConnectedComponents.cpp
 *
 *  Created on: Dec 16, 2013
 *      Author: cls
 */

#include "ConnectedComponents.h"
#include "../structures/Partition.h"
#include "../coarsening/PartitionCoarsening.h"
#include <set>

namespace NetworKit {

ConnectedComponents::ConnectedComponents() {

}

ConnectedComponents::~ConnectedComponents() {

}

void ConnectedComponents::run(const Graph& G) {
	// calculate connected components by label propagation
	count z = G.numberOfNodes();
	this->component = std::vector<node>(z, none);

	DEBUG("initializing labels");
	Partition partition(G.upperNodeIdBound());
	partition.allToSingletons();

	DEBUG("initializing active nodes");
	std::vector<bool> activeNodes(z); // record if node must be processed
	activeNodes.assign(z, true);
	G.forNodes([&](node u) { // NOTE: not in parallel due to implementation of bit vector
		if (G.degree(u) == 0) {
			activeNodes[u] = false;
		}
	});

	DEBUG("main loop");
//	count numActive = 0; // for debugging purposes only
	count numIterations = 0;
	bool change = false;
	do {
//		TRACE("label propagation iteration");
		change = false;
//		numActive = 0;
		G.forNodes([&](node u) {
			if (activeNodes[u]) {
//				++numActive;
				std::vector<index> neighborLabels;
				G.forNeighborsOf(u, [&](node v) {
					// neighborLabels.push_back(component[v]);
					neighborLabels.push_back(partition[v]);
				});
				// get smallest
				index smallest = *std::min_element(neighborLabels.begin(), neighborLabels.end());

				if (partition[u] != smallest) {
					partition.moveToSubset(smallest, u);
					change = true;
					G.forNeighborsOf(u, [&](node v) {
						activeNodes[v] = true;
					});
				} else {
					activeNodes[u] = false; // current node becomes inactive
				}
			}
		});
//		TRACE("num active: ", numActive);
		++numIterations;
		if ((numIterations % 10) == 0) {
			// coarsen and make recursive call
			PartitionCoarsening con;
			std::pair<Graph, std::vector<node> > coarse = con.run(G, partition);
			ConnectedComponents cc;
			cc.run(coarse.first);

			// apply to current graph
			G.forNodes([&](node u) {
				partition[u] = cc.componentOfNode(coarse.second[u]);
			});
		}
	} while (change);

	G.parallelForNodes([&](node u) {
		component[u] = partition[u];
	});
}

std::vector<index> ConnectedComponents::getComponentData() {
	return this->component;
}

std::map<index, count> ConnectedComponents::getComponentSizes() {
	std::map<index, count> componentSize;
	for (node u = 0; u < component.size(); ++u) {
		if (component[u] != none) {
			componentSize[component[u]] += 1;
		}
	}
	return componentSize;
}

std::vector<node> ConnectedComponents::getComponent(index label) {
	std::vector<node> nodesOfComponent;
	for (node u = 0; u < component.size(); ++u) {
		if (this->component[u] == label) {
			nodesOfComponent.push_back(u);
		}
	}
	return nodesOfComponent;
}

count ConnectedComponents::numberOfComponents() {
	count nc = 0;
	std::set<index> componentLabels;
	for (index i = 0; i < component.size(); ++i) {
		index c = component[i];
		if ((componentLabels.find(c) == componentLabels.end()) && (c != none)) { // label not encountered yet
			componentLabels.insert(c);
			nc++;
		}
	}
	return nc;
}

count ConnectedComponents::componentOfNode(node u) {
	assert (component[u] != none);
	return component[u];
}

}

<|endoftext|>


<commit_before>#pragma once
#include "higanbana/core/coroutine/coroutine_pool.hpp"
#include <experimental/coroutine>

namespace higanbana
{
namespace coro
{
struct suspend_never {
  constexpr bool await_ready() const noexcept { return true; }
  void await_suspend(std::experimental::coroutine_handle<>) const noexcept {}
  constexpr void await_resume() const noexcept {}
};

struct suspend_always {
  constexpr bool await_ready() const noexcept { return false; }
  void await_suspend(std::experimental::coroutine_handle<>) const noexcept {}
  constexpr void await_resume() const noexcept {}
};
struct noop_task {
  struct promise_type {
    noop_task get_return_object() noexcept {
      return { std::experimental::coroutine_handle<promise_type>::from_promise(*this) };
    }
    void unhandled_exception() noexcept {}
    void return_void() noexcept {}
    suspend_always initial_suspend() noexcept { return {}; }
    suspend_never final_suspend() noexcept { return {}; }
  };
  std::experimental::coroutine_handle<> coro;
};

std::experimental::coroutine_handle<> noop_coroutine() noexcept;
std::experimental::coroutine_handle<> noop_coroutine(experimental::Barrier dep) noexcept;

extern thread_local bool thread_first_seen_coroutine;
extern thread_local bool thread_inside_coroutine;
extern thread_local int thread_coroutine_depth;
template<typename T>
class Task {
public:
  struct promise_type {
    using coro_handle = std::experimental::coroutine_handle<promise_type>;
    __declspec(noinline) auto get_return_object() noexcept {
      return Task(coro_handle::from_promise(*this));
    }
    constexpr suspend_always initial_suspend() noexcept {
      return {};
    }

    struct final_awaiter {
      constexpr bool await_ready() noexcept {
        return false;
      }
      template<typename U>
      std::experimental::coroutine_handle<> await_suspend(U h) noexcept {
        auto cont_handle = std::move(h.promise().m_continuation);
        if (cont_handle.address() != nullptr){
          thread_first_seen_coroutine = false;
          thread_coroutine_depth++;
          auto copy = std::move(h.promise().finalDependency);
          copy.kill();
          return cont_handle;
        }
        thread_coroutine_depth = 0;
        return noop_coroutine(std::move(h.promise().finalDependency));
      }
      void await_resume() noexcept {}
    };

    final_awaiter final_suspend() noexcept {
      return {};
    }
    void return_value(T value) noexcept {m_value = std::move(value);}
    void unhandled_exception() noexcept {
      std::terminate();
    }
    T m_value;
    bool async = false;
    experimental::BarrierObserver bar;
    experimental::Barrier finalDependency;
    std::experimental::coroutine_handle<> m_continuation;
  };
  using coro_handle = std::experimental::coroutine_handle<promise_type>;
  Task(coro_handle handle) noexcept : handle_(handle)
  {
    assert(handle);
    handle_.promise().finalDependency = experimental::Barrier();
    if (!thread_inside_coroutine || thread_first_seen_coroutine || thread_coroutine_depth > 2) {
      handle_.promise().async = true;
      handle_.promise().bar = experimental::globals::s_pool->task({}, [handlePtr = handle_.address()](size_t) mutable {
        auto handle = coro_handle::from_address(handlePtr);
        thread_first_seen_coroutine = false;
        thread_inside_coroutine = true;
        thread_coroutine_depth = 0;
        handle.resume();
        thread_inside_coroutine = false;
      });
    }
    thread_first_seen_coroutine = true;
  }
  Task(Task& other) noexcept {
    handle_ = other.handle_;
  };
  Task(Task&& other) noexcept {
    if (other.handle_)
      handle_ = std::move(other.handle_);
    assert(handle_);
    other.handle_ = nullptr;
  }
  Task& operator=(Task& other) noexcept {
    handle_ = other.handle_;
    return *this;
  };
  Task& operator=(Task&& other) noexcept {
    if (other.handle_)
      handle_ = std::move(other.handle_);
    assert(handle_);
    other.handle_ = nullptr;
    return *this;
  }
  T await_resume() noexcept {
    return handle_.promise().m_value;
  }
  bool await_ready() noexcept {
    return handle_.done();
  }

  // enemy coroutine needs this coroutines result, therefore we compute it.
  template<typename HopefullyCoroHandleWithMyPromise>
  std::experimental::coroutine_handle<> await_suspend(HopefullyCoroHandleWithMyPromise handle) noexcept {
    if(handle_.promise().async)
    {
      experimental::BarrierObserver obs;
      auto finalDep = handle_.promise().finalDependency;
      if (finalDep)
        obs = experimental::BarrierObserver(finalDep);
      if (!obs.done() || !handle_.done()) {
        experimental::Barrier temp;
        experimental::BarrierObserver tobs(temp);
        handle.promise().async = true;
        HIGAN_ASSERT(experimental::globals::s_pool, "thread pool not available, error");
        handle.promise().bar = experimental::globals::s_pool->task({std::move(obs), handle.promise().bar, tobs}, [handlePtr = handle.address()](size_t) mutable {
          auto handle = coro_handle::from_address(handlePtr);
          thread_first_seen_coroutine = false;
          thread_inside_coroutine = true;
          thread_coroutine_depth = 0;
          handle.resume();
          thread_inside_coroutine = false;
        });
        thread_coroutine_depth = 0;
        return noop_coroutine(temp);
      }
      else
      {
        return handle;
      }
    }

    //assert(!handle_.done() && !handle_.promise().finalDependency.done());
    handle_.promise().m_continuation = handle;
    thread_first_seen_coroutine = false;
    thread_coroutine_depth++;
    return handle_;
  }
  ~Task() noexcept {
    if (handle_ && handle_.done()) {
      assert(handle_.done());
      handle_.destroy();
    }
  }

  T get() noexcept
  {
    auto obs = experimental::BarrierObserver(handle_.promise().finalDependency);
    bool wasIAsync = handle_.promise().async;
    while(!handle_.done()){
      if (handle_.promise().async)
        experimental::globals::s_pool->helpTasksUntilBarrierComplete(obs);
      else {
        handle_.resume();
        if (!wasIAsync && handle_.promise().async)
        {
          wasIAsync = true;
          //printf("Am async now! \n");
        }
      }
    }
    // we are exiting here too fast, somebody with stack left and our destruction kills it.
    assert(experimental::BarrierObserver(handle_.promise().finalDependency).done());
    assert(handle_.done());
    return handle_.promise().m_value;
  }
  bool is_ready() const {
    return handle_ && handle_.done();
  }
  explicit operator bool() const {
    return handle_.address() != nullptr;
  }
  // unwrap() future<future<int>> -> future<int>
  // future then(lambda) -> attach function to be done after current Task.
  // is_ready() are you ready?
private:
  std::experimental::coroutine_handle<promise_type> handle_;
};

// void version
template <>
class Task<void> {
public:
  struct promise_type {
    using coro_handle = std::experimental::coroutine_handle<promise_type>;
    __declspec(noinline) auto get_return_object() noexcept {
      return Task(coro_handle::from_promise(*this));
    }
    constexpr suspend_always initial_suspend() noexcept {
      return {};
    }

    struct final_awaiter {
      constexpr bool await_ready() noexcept {
        return false;
      }

      template<typename U>
      std::experimental::coroutine_handle<> await_suspend(U h) noexcept {
        if (h.promise().m_continuation.address() != nullptr){
          return h.promise().m_continuation;
        }
        return noop_coroutine(std::move(h.promise().finalDependency));
      }
      void await_resume() noexcept {}
    };

    final_awaiter final_suspend() noexcept {
      return {};
    }
    void return_void() noexcept {}
    void unhandled_exception() noexcept {
      std::terminate();
    }
    bool async = false;
    experimental::BarrierObserver bar;
    experimental::Barrier finalDependency;
    std::experimental::coroutine_handle<> m_continuation;
  };
  using coro_handle = std::experimental::coroutine_handle<promise_type>;
  Task(coro_handle handle) noexcept : handle_(handle)
  {
    assert(handle);
    handle_.promise().finalDependency = experimental::Barrier();
    handle_.promise().async = true;
    handle_.promise().bar = experimental::globals::s_pool->task({}, [handlePtr = handle_.address()](size_t) mutable {
      auto handle = coro_handle::from_address(handlePtr);
      handle.resume();
    });
  }
  Task(Task& other) noexcept {
    handle_ = other.handle_;
  };
  Task(Task&& other) noexcept {
    if (other.handle_)
      handle_ = std::move(other.handle_);
    assert(handle_);
    other.handle_ = nullptr;
  }
  Task& operator=(Task& other) noexcept {
    handle_ = other.handle_;
    return *this;
  };
  Task& operator=(Task&& other) noexcept {
    if (other.handle_)
      handle_ = std::move(other.handle_);
    assert(handle_);
    other.handle_ = nullptr;
    return *this;
  }
  void await_resume() noexcept {
  }
  bool await_ready() noexcept {
    return handle_.done();
  }

  // enemy coroutine needs this coroutines result, therefore we compute it.
  template<typename HopefullyCoroHandleWithMyPromise>
  std::experimental::coroutine_handle<> await_suspend(HopefullyCoroHandleWithMyPromise handle) noexcept {
    if(handle_.promise().async)
    {
      experimental::BarrierObserver obs;
      auto finalDep = handle_.promise().finalDependency;
      if (finalDep)
        obs = experimental::BarrierObserver(finalDep);
      experimental::Barrier temp;
      experimental::BarrierObserver tobs(temp);
      handle.promise().async = true;
      HIGAN_ASSERT(experimental::globals::s_pool, "thread pool not available, error");
      handle.promise().bar = experimental::globals::s_pool->task({std::move(obs), handle.promise().bar, tobs}, [handlePtr = handle.address()](size_t) mutable {
        auto handle = coro_handle::from_address(handlePtr);
        assert(!handle.done());
        handle.resume();
      });
      return noop_coroutine(temp);
    }
    handle_.promise().m_continuation = handle;
    return handle_;
  }
  ~Task() noexcept {
    if (handle_ && handle_.done()) {
      assert(handle_.done());
      handle_.destroy();
    }
  }

  void wait() noexcept
  {
    auto obs = experimental::BarrierObserver(handle_.promise().finalDependency);
    bool wasIAsync = handle_.promise().async;
    while(!handle_.done()){
      if (handle_.promise().async)
        experimental::globals::s_pool->helpTasksUntilBarrierComplete(obs);
      else {
        handle_.resume();
        if (!wasIAsync && handle_.promise().async)
        {
          wasIAsync = true;
          //printf("Am async now! \n");
        }
      }
    }
    // we are exiting here too fast, somebody with stack left and our destruction kills it.
    assert(experimental::BarrierObserver(handle_.promise().finalDependency).done());
    assert(handle_.done());
  }

  bool is_ready() const {
    return handle_ && handle_.done();
  }
  explicit operator bool() const {
    return !handle_.done();
  }
  // unwrap() future<future<int>> -> future<int>
  // future then(lambda) -> attach function to be done after current Task.
  // is_ready() are you ready?
private:
  std::experimental::coroutine_handle<promise_type> handle_;
};

template<typename Func>
Task<void> runAsync(Func&& f)
{
  f();
  co_return;
}

}
}<commit_msg>Fixed bugs with propagating results<commit_after>#pragma once
#include "higanbana/core/coroutine/coroutine_pool.hpp"
#include <experimental/coroutine>

namespace higanbana
{
namespace coro
{
struct suspend_never {
  constexpr bool await_ready() const noexcept { return true; }
  void await_suspend(std::experimental::coroutine_handle<>) const noexcept {}
  constexpr void await_resume() const noexcept {}
};

struct suspend_always {
  constexpr bool await_ready() const noexcept { return false; }
  void await_suspend(std::experimental::coroutine_handle<>) const noexcept {}
  constexpr void await_resume() const noexcept {}
};
struct noop_task {
  struct promise_type {
    noop_task get_return_object() noexcept {
      return { std::experimental::coroutine_handle<promise_type>::from_promise(*this) };
    }
    void unhandled_exception() noexcept {}
    void return_void() noexcept {}
    suspend_always initial_suspend() noexcept { return {}; }
    suspend_never final_suspend() noexcept { return {}; }
  };
  std::experimental::coroutine_handle<> coro;
};

std::experimental::coroutine_handle<> noop_coroutine() noexcept;
std::experimental::coroutine_handle<> noop_coroutine(experimental::Barrier dep) noexcept;

extern thread_local bool thread_first_seen_coroutine;
extern thread_local bool thread_inside_coroutine;
extern thread_local int thread_coroutine_depth;
template<typename T>
class Task {
public:
  struct promise_type {
    using coro_handle = std::experimental::coroutine_handle<promise_type>;
    __declspec(noinline) auto get_return_object() noexcept {
      return Task(coro_handle::from_promise(*this));
    }
    constexpr suspend_always initial_suspend() noexcept {
      return {};
    }

    struct final_awaiter {
      constexpr bool await_ready() noexcept {
        return false;
      }
      template<typename U>
      std::experimental::coroutine_handle<> await_suspend(U h) noexcept {
        auto cont_handle = std::move(h.promise().m_continuation);
        if (cont_handle.address() != nullptr){
          thread_first_seen_coroutine = false;
          thread_coroutine_depth++;
          auto copy = std::move(h.promise().finalDependency);
          copy.kill();
          return cont_handle;
        }
        return noop_coroutine(std::move(h.promise().finalDependency));
      }
      void await_resume() noexcept {}
    };

    final_awaiter final_suspend() noexcept {
      return {};
    }
    void return_value(T value) noexcept {m_value = std::move(value);}
    void unhandled_exception() noexcept {
      std::terminate();
    }
    T m_value;
    bool async = false;
    experimental::BarrierObserver bar;
    experimental::Barrier finalDependency;
    std::experimental::coroutine_handle<> m_continuation;
  };
  using coro_handle = std::experimental::coroutine_handle<promise_type>;
  Task(coro_handle handle) noexcept : handle_(handle)
  {
    assert(handle);
    handle_.promise().finalDependency = experimental::Barrier();
    if (!thread_inside_coroutine || thread_first_seen_coroutine || thread_coroutine_depth > 1) {
      handle_.promise().async = true;
      handle_.promise().bar = experimental::globals::s_pool->task({}, [handlePtr = handle_.address()](size_t) mutable {
        auto handle = coro_handle::from_address(handlePtr);
        thread_first_seen_coroutine = false;
        thread_inside_coroutine = true;
        thread_coroutine_depth = 0;
        handle.resume();
        thread_inside_coroutine = false;
      });
    }
    thread_first_seen_coroutine = true;
  }
  Task(Task& other) noexcept {
    handle_ = other.handle_;
  };
  Task(Task&& other) noexcept {
    if (other.handle_)
      handle_ = std::move(other.handle_);
    assert(handle_);
    other.handle_ = nullptr;
  }
  Task& operator=(Task& other) noexcept {
    handle_ = other.handle_;
    return *this;
  };
  Task& operator=(Task&& other) noexcept {
    if (other.handle_)
      handle_ = std::move(other.handle_);
    assert(handle_);
    other.handle_ = nullptr;
    return *this;
  }
  T await_resume() noexcept {
    return handle_.promise().m_value;
  }
  bool await_ready() noexcept {
    return handle_.done();
  }

  // enemy coroutine needs this coroutines result, therefore we compute it.
  template<typename HopefullyCoroHandleWithMyPromise>
  std::experimental::coroutine_handle<> await_suspend(HopefullyCoroHandleWithMyPromise handle) noexcept {
    if(handle_.promise().async)
    {
      experimental::BarrierObserver obs;
      auto finalDep = handle_.promise().finalDependency;
      if (finalDep)
        obs = experimental::BarrierObserver(finalDep);
      if (!obs.done() || !handle_.done()) {
        experimental::Barrier temp;
        experimental::BarrierObserver tobs(temp);
        handle.promise().async = true;
        HIGAN_ASSERT(experimental::globals::s_pool, "thread pool not available, error");
        handle.promise().bar = experimental::globals::s_pool->task({std::move(obs), handle.promise().bar, tobs}, [handlePtr = handle.address()](size_t) mutable {
          auto handle = coro_handle::from_address(handlePtr);
          thread_first_seen_coroutine = false;
          thread_inside_coroutine = true;
          thread_coroutine_depth = 0;
          handle.resume();
          thread_inside_coroutine = false;
        });
        thread_coroutine_depth = 0;
        return noop_coroutine(temp);
      }
      else
      {
        return handle;
      }
    }

    handle_.promise().m_continuation = handle;
    thread_first_seen_coroutine = false;
    thread_coroutine_depth++;
    return handle_;
  }
  ~Task() noexcept {
    if (handle_ && handle_.done()) {
      assert(handle_.done());
      handle_.destroy();
    }
  }

  T get() noexcept
  {
    auto obs = experimental::BarrierObserver(handle_.promise().finalDependency);
    bool wasIAsync = handle_.promise().async;
    while(!handle_.done()){
      if (handle_.promise().async)
        experimental::globals::s_pool->helpTasksUntilBarrierComplete(obs);
      else {
        handle_.resume();
        if (!wasIAsync && handle_.promise().async)
        {
          wasIAsync = true;
          //printf("Am async now! \n");
        }
      }
    }
    // we are exiting here too fast, somebody with stack left and our destruction kills it.
    assert(experimental::BarrierObserver(handle_.promise().finalDependency).done());
    assert(handle_.done());
    return handle_.promise().m_value;
  }
  bool is_ready() const {
    return handle_ && handle_.done();
  }
  explicit operator bool() const {
    return handle_.address() != nullptr;
  }
  // unwrap() future<future<int>> -> future<int>
  // future then(lambda) -> attach function to be done after current Task.
  // is_ready() are you ready?
private:
  std::experimental::coroutine_handle<promise_type> handle_;
};

// void version
template <>
class Task<void> {
public:
  struct promise_type {
    using coro_handle = std::experimental::coroutine_handle<promise_type>;
    __declspec(noinline) auto get_return_object() noexcept {
      return Task(coro_handle::from_promise(*this));
    }
    constexpr suspend_always initial_suspend() noexcept {
      return {};
    }

    struct final_awaiter {
      constexpr bool await_ready() noexcept {
        return false;
      }

      template<typename U>
      std::experimental::coroutine_handle<> await_suspend(U h) noexcept {
        auto cont_handle = std::move(h.promise().m_continuation);
        if (cont_handle.address() != nullptr){
          thread_first_seen_coroutine = false;
          thread_coroutine_depth++;
          auto copy = std::move(h.promise().finalDependency);
          copy.kill();
          return cont_handle;
        }
        return noop_coroutine(std::move(h.promise().finalDependency));
      }
      void await_resume() noexcept {}
    };

    final_awaiter final_suspend() noexcept {
      return {};
    }
    void return_void() noexcept {}
    void unhandled_exception() noexcept {
      std::terminate();
    }
    bool async = false;
    experimental::BarrierObserver bar;
    experimental::Barrier finalDependency;
    std::experimental::coroutine_handle<> m_continuation;
  };
  using coro_handle = std::experimental::coroutine_handle<promise_type>;
  Task(coro_handle handle) noexcept : handle_(handle)
  {
    assert(handle);
    if (!thread_inside_coroutine || thread_first_seen_coroutine || thread_coroutine_depth > 1) {
      handle_.promise().async = true;
      handle_.promise().bar = experimental::globals::s_pool->task({}, [handlePtr = handle_.address()](size_t) mutable {
        auto handle = coro_handle::from_address(handlePtr);
        thread_first_seen_coroutine = false;
        thread_inside_coroutine = true;
        thread_coroutine_depth = 0;
        handle.resume();
        thread_inside_coroutine = false;
      });
    }
    thread_first_seen_coroutine = true;
  }
  Task(Task& other) noexcept {
    handle_ = other.handle_;
  };
  Task(Task&& other) noexcept {
    if (other.handle_)
      handle_ = std::move(other.handle_);
    assert(handle_);
    other.handle_ = nullptr;
  }
  Task& operator=(Task& other) noexcept {
    handle_ = other.handle_;
    return *this;
  };
  Task& operator=(Task&& other) noexcept {
    if (other.handle_)
      handle_ = std::move(other.handle_);
    assert(handle_);
    other.handle_ = nullptr;
    return *this;
  }
  void await_resume() noexcept {
  }
  bool await_ready() noexcept {
    return handle_.done();
  }

  // enemy coroutine needs this coroutines result, therefore we compute it.
  template<typename HopefullyCoroHandleWithMyPromise>
  std::experimental::coroutine_handle<> await_suspend(HopefullyCoroHandleWithMyPromise handle) noexcept {
    if(handle_.promise().async)
    {
      experimental::BarrierObserver obs;
      auto finalDep = handle_.promise().finalDependency;
      if (finalDep)
        obs = experimental::BarrierObserver(finalDep);
      if (!obs.done() || !handle_.done()) {
        experimental::Barrier temp;
        experimental::BarrierObserver tobs(temp);
        handle.promise().async = true;
        HIGAN_ASSERT(experimental::globals::s_pool, "thread pool not available, error");
        handle.promise().bar = experimental::globals::s_pool->task({std::move(obs), handle.promise().bar, tobs}, [handlePtr = handle.address()](size_t) mutable {
          auto handle = coro_handle::from_address(handlePtr);
          thread_first_seen_coroutine = false;
          thread_inside_coroutine = true;
          thread_coroutine_depth = 0;
          handle.resume();
          thread_inside_coroutine = false;
        });
        thread_coroutine_depth = 0;
        return noop_coroutine(temp);
      }
      else
      {
        return handle;
      }
    }

    handle_.promise().m_continuation = handle;
    thread_first_seen_coroutine = false;
    thread_coroutine_depth++;
    return handle_;
  }
  ~Task() noexcept {
    if (handle_ && handle_.done()) {
      assert(handle_.done());
      handle_.destroy();
    }
  }

  void wait() noexcept
  {
    auto obs = experimental::BarrierObserver(handle_.promise().finalDependency);
    bool wasIAsync = handle_.promise().async;
    while(!handle_.done()){
      if (handle_.promise().async)
        experimental::globals::s_pool->helpTasksUntilBarrierComplete(obs);
      else {
        handle_.resume();
        if (!wasIAsync && handle_.promise().async)
        {
          wasIAsync = true;
          //printf("Am async now! \n");
        }
      }
    }
    // we are exiting here too fast, somebody with stack left and our destruction kills it.
    assert(experimental::BarrierObserver(handle_.promise().finalDependency).done());
    assert(handle_.done());
  }

  bool is_ready() const {
    return handle_ && handle_.done();
  }
  explicit operator bool() const {
    return !handle_.done();
  }
  // unwrap() future<future<int>> -> future<int>
  // future then(lambda) -> attach function to be done after current Task.
  // is_ready() are you ready?
private:
  std::experimental::coroutine_handle<promise_type> handle_;
};

template<typename Func>
Task<void> runAsync(Func&& f)
{
  f();
  co_return;
}

}
}<|endoftext|>


<commit_before>#pragma once
/*
 * FastaRecord.hpp
 *
 *  Created on: Sep 21, 2015
 *      Author: nick
 */

#include "TwoBit/utils.h"
#include <cppitertools/range.hpp>

namespace TwoBit {

class FastaRecord {
public:
	/**@brief Constructor with universal reference so that large strings can be moved from
	 *
	 * @param name The name of the sequene
	 * @param seq The seqeunce to store, can be a lvalue or rvalue reference to optimize not having to copy large strings
	 */
	template<typename T>
	FastaRecord(const std::string & name, T && seq) :
			name_(name), seq_(std::forward<T>(seq)) {
		static_assert(std::is_constructible<std::string, T>::value,
				"Parameter seq can't be used to construct a std::string in constructing seqInfo");
		unknownToN(seq_);
		//determine masks and ns
		storeBlocksOfLower();
		storeBlocksOfN();
	}

	std::string name_;/**< The name of the sequence*/
	std::string seq_;/**< The sequence */
	std::vector<uint32_t> nStarts_;/**< The start sites of the n regions*/
	std::vector<uint32_t> nSizes_;/**< The sizes of the n regions*/
	std::vector<uint32_t> maskStarts_;/**< The start sites of the masked regions*/
	std::vector<uint32_t> maskSizes_;/**< The sizes of the masked regions*/
	uint32_t reserved_;/**< Reserved for future use in the twobit format*/
	/**@brief convert seq_ into a vector of unsinged char with two bits per base
	 *
	 * @return seq_ converted into a vec of unsigned char with two bits per base info
	 */
	std::vector<unsigned char> data()const;
private:
	/**@brief Store starts and sizes of blocks of N's
	 *
	 * @param str The string to analyze
	 * @param starts The vec to store start positions
	 * @param sizes The vec to store sizes of blocks
	 */
	void storeBlocksOfN();
	/**@brief Store starts and sizes of blocks of lower case letters
	 *
	 * @param str The string to analyze
	 * @param starts The vec to store start positions
	 * @param sizes The vec to store sizes of blocks
	 */
	void storeBlocksOfLower();
public:
	/**@brief Figure out size structure will take in file
	 *
	 * @return The size the sequence is going to take up
	 */
	int twoBitSizeInFile()const;

	/**@brief Write out one twoBit sequence to binary file
	 * Note this does not include the name, which is
	 * stored only in index
	 * @param out The file to write to
	 */
	void twoBitWriteOne(std::ofstream & out) const;
};

}  // namespace TwoBit
<commit_msg>forgot to initialize reserved_ to zero (so it was just set as a random number)<commit_after>#pragma once
/*
 * FastaRecord.hpp
 *
 *  Created on: Sep 21, 2015
 *      Author: nick
 */

#include "TwoBit/utils.h"
#include <cppitertools/range.hpp>

namespace TwoBit {

class FastaRecord {
public:
	/**@brief Constructor with universal reference so that large strings can be moved from
	 *
	 * @param name The name of the sequene
	 * @param seq The seqeunce to store, can be a lvalue or rvalue reference to optimize not having to copy large strings
	 */
	template<typename T>
	FastaRecord(const std::string & name, T && seq) :
			name_(name), seq_(std::forward<T>(seq)) {
		static_assert(std::is_constructible<std::string, T>::value,
				"Parameter seq can't be used to construct a std::string in constructing seqInfo");
		unknownToN(seq_);
		//determine masks and ns
		storeBlocksOfLower();
		storeBlocksOfN();
	}

	std::string name_;/**< The name of the sequence*/
	std::string seq_;/**< The sequence */
	std::vector<uint32_t> nStarts_;/**< The start sites of the n regions*/
	std::vector<uint32_t> nSizes_;/**< The sizes of the n regions*/
	std::vector<uint32_t> maskStarts_;/**< The start sites of the masked regions*/
	std::vector<uint32_t> maskSizes_;/**< The sizes of the masked regions*/
	uint32_t reserved_ = 0;/**< Reserved for future use in the twobit format*/
	/**@brief convert seq_ into a vector of unsinged char with two bits per base
	 *
	 * @return seq_ converted into a vec of unsigned char with two bits per base info
	 */
	std::vector<unsigned char> data()const;
private:
	/**@brief Store starts and sizes of blocks of N's
	 *
	 * @param str The string to analyze
	 * @param starts The vec to store start positions
	 * @param sizes The vec to store sizes of blocks
	 */
	void storeBlocksOfN();
	/**@brief Store starts and sizes of blocks of lower case letters
	 *
	 * @param str The string to analyze
	 * @param starts The vec to store start positions
	 * @param sizes The vec to store sizes of blocks
	 */
	void storeBlocksOfLower();
public:
	/**@brief Figure out size structure will take in file
	 *
	 * @return The size the sequence is going to take up
	 */
	int twoBitSizeInFile()const;

	/**@brief Write out one twoBit sequence to binary file
	 * Note this does not include the name, which is
	 * stored only in index
	 * @param out The file to write to
	 */
	void twoBitWriteOne(std::ofstream & out) const;
};

}  // namespace TwoBit
<|endoftext|>


<commit_before>#include <typeinfo>
#include <iostream>
#include <fstream>
#include <sstream>
#include <cassert>
#include <vector>

using namespace std;

std::vector<std::string> Tokenize(const std::string& str,
    const std::string& delimiters = " \t");

template<typename T>
inline T Scan(const std::string &input)
{
  std::stringstream stream(input);
  T ret;
  stream >> ret;
  return ret;
}

class FF
{
  friend std::ostream& operator<<(std::ostream &out, const FF&);

  virtual void Output(std::ostream &out) const = 0;
public:
  vector<string> toks;
  string name;
  string path;
  int index, numFeatures;

  FF(const string &line)
  {
    toks = Tokenize(line, ":");
  }

  virtual string ffType() const= 0;
};

std::ostream& operator<<(std::ostream &out, const FF &model)
{
  model.Output(out);
  return out;
}

class LM : public FF
{
  static int s_index;

  void Output(std::ostream &out) const
  {
    out << name << index << " "
        << " order=" << order
        << " factor=" << factor
        << " path=" << path
        << " " << otherArgs;
  }
public:
  string otherArgs;
  int order, factor;

  LM(const string &line)
  :FF(line)
  {
    numFeatures = 1;

    factor = Scan<int>(toks[0]);
    order = Scan<int>(toks[1]);
    path = toks[2];
    int implNum = Scan<int>(toks[3]);

    switch (implNum)
    {
      case 0: name = "SRILM"; break;
      case 1: name = "IRSTLM"; break;
      case 8: name = "KENLM"; otherArgs = "lazyken=0"; break;
      case 9: name = "KENLM"; otherArgs = "lazyken=1"; break;
    }
  }

  string ffType() const
  { return "LM"; }
};

class RO : public FF
{
  static int s_index;

  void Output(std::ostream &out) const
  {
    out << name << index << " "
        << " path=" << path;
  }
public:

  RO(const string &line)
  :FF(line)
  {
    name = "LexicalReordering";
    numFeatures = 6;
    path = toks[0];
  }

  string ffType() const
  { return "RO"; }
};

class Pt : public FF
{
  static int s_index;

  void Output(std::ostream &out) const
  {
    out << name << index << " "
        << " path=" << path;
  }
public:
  int numFeatures;
  vector<int> inFactor, outFactor;

  Pt(const string &line)
  :FF(line)
  {
    index = s_index++;
    name = "PhraseModel";
    numFeatures = 5;
    path = toks[0];

    inFactor.push_back(0);
    outFactor.push_back(0);
  }

  string ffType() const
  { return "Pt"; }
};

int Pt::s_index = 0;

string iniPath;
vector<FF*> ffVec;

void OutputWeights(stringstream &weightStrme, const FF &ff)
{
}

void Output()
{
  ofstream strme(iniPath.c_str());
  stringstream weightStrme;

  weightStrme << "[weight]" << endl;

  strme << "[input-factors]" << endl;
  strme << "0" << endl;

  strme << "[mapping]" << endl;
  strme << "0 T 0" << endl;

  strme << "[distortion-limit]" << endl;
  strme << "6" << endl;

  strme << "[feature]" << endl;
  for (size_t i = 0; i < ffVec.size(); ++i) {
    const FF &ff = *ffVec[i];

    strme << ff << endl;

    OutputWeights(weightStrme, ff);
  }

  strme << weightStrme.str();

  strme.close();
}

int main(int argc, char **argv)
{
  for (int i = 0; i < argc; ++i) {
    string key(argv[i]);

    if (key == "-phrase-translation-table") {
      ++i;
      Pt *model = new Pt(argv[i]);
      ffVec.push_back(model);
    }
    else if (key == "-reordering-table") {
      ++i;
      RO *model = new RO(argv[i]);
      ffVec.push_back(model);
    }
    else if (key == "-lm") {
      ++i;
      LM *model = new LM(argv[i]);
      ffVec.push_back(model);
    }
    else if (key == "-config") {
      ++i;
      iniPath = argv[i];
    }
  }

  Output();
}

std::vector<std::string> Tokenize(const std::string& str,
    const std::string& delimiters)
{
  std::vector<std::string> tokens;
  // Skip delimiters at beginning.
  std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
  // Find first "non-delimiter".
  std::string::size_type pos     = str.find_first_of(delimiters, lastPos);

  while (std::string::npos != pos || std::string::npos != lastPos) {
    // Found a token, add it to the vector.
    tokens.push_back(str.substr(lastPos, pos - lastPos));
    // Skip delimiters.  Note the "not_of"
    lastPos = str.find_first_not_of(delimiters, pos);
    // Find next "non-delimiter"
    pos = str.find_first_of(delimiters, lastPos);
  }

  return tokens;
}

<commit_msg>create-ini.cpp<commit_after>#include <typeinfo>
#include <iostream>
#include <fstream>
#include <sstream>
#include <cassert>
#include <vector>

using namespace std;

std::vector<std::string> Tokenize(const std::string& str,
    const std::string& delimiters = " \t");

template<typename T>
inline T Scan(const std::string &input)
{
  std::stringstream stream(input);
  T ret;
  stream >> ret;
  return ret;
}

class FF
{
  friend std::ostream& operator<<(std::ostream &out, const FF&);

  virtual void Output(std::ostream &out) const = 0;
  virtual void OutputWeights(std::ostream &out) const
  {
    out << name << index << "= ";
    for (size_t i = 0; i < numFeatures; ++i) {

    }
  }

public:
  vector<string> toks;
  string name;
  string path;
  int index, numFeatures;

  FF(const string &line)
  {
    toks = Tokenize(line, ":");
  }

  virtual string ffType() const= 0;
};

std::ostream& operator<<(std::ostream &out, const FF &model)
{
  model.Output(out);
  return out;
}

class LM : public FF
{
  static int s_index;

  void Output(std::ostream &out) const
  {
    out << name << index << " "
        << " order=" << order
        << " factor=" << factor
        << " path=" << path
        << " " << otherArgs;
  }

public:
  string otherArgs;
  int order, factor;

  LM(const string &line)
  :FF(line)
  {
    numFeatures = 1;

    factor = Scan<int>(toks[0]);
    order = Scan<int>(toks[1]);
    path = toks[2];
    int implNum = Scan<int>(toks[3]);

    switch (implNum)
    {
      case 0: name = "SRILM"; break;
      case 1: name = "IRSTLM"; break;
      case 8: name = "KENLM"; otherArgs = "lazyken=0"; break;
      case 9: name = "KENLM"; otherArgs = "lazyken=1"; break;
    }
  }

  string ffType() const
  { return "LM"; }
};

class RO : public FF
{
  static int s_index;

  void Output(std::ostream &out) const
  {
    out << name << index << " "
        << " path=" << path;
  }
public:

  RO(const string &line)
  :FF(line)
  {
    name = "LexicalReordering";
    numFeatures = 6;
    path = toks[0];
  }

  string ffType() const
  { return "RO"; }
};

class Pt : public FF
{
  static int s_index;

  void Output(std::ostream &out) const
  {
    out << name << index << " "
        << " path=" << path;
  }
public:
  int numFeatures;
  vector<int> inFactor, outFactor;

  Pt(const string &line)
  :FF(line)
  {
    index = s_index++;
    name = "PhraseModel";
    numFeatures = 5;
    path = toks[0];

    inFactor.push_back(0);
    outFactor.push_back(0);
  }

  string ffType() const
  { return "Pt"; }
};

int Pt::s_index = 0;

string iniPath;
vector<FF*> ffVec;

void OutputWeights(stringstream &weightStrme, const FF &ff)
{
}

void Output()
{
  ofstream strme(iniPath.c_str());
  stringstream weightStrme;

  weightStrme << "[weight]" << endl;

  strme << "[input-factors]" << endl;
  strme << "0" << endl;

  strme << "[mapping]" << endl;
  strme << "0 T 0" << endl;

  strme << "[distortion-limit]" << endl;
  strme << "6" << endl;

  strme << "[feature]" << endl;
  for (size_t i = 0; i < ffVec.size(); ++i) {
    const FF &ff = *ffVec[i];

    strme << ff << endl;

    OutputWeights(weightStrme, ff);
  }

  strme << weightStrme.str();

  strme.close();
}

int main(int argc, char **argv)
{
  for (int i = 0; i < argc; ++i) {
    string key(argv[i]);

    if (key == "-phrase-translation-table") {
      ++i;
      Pt *model = new Pt(argv[i]);
      ffVec.push_back(model);
    }
    else if (key == "-reordering-table") {
      ++i;
      RO *model = new RO(argv[i]);
      ffVec.push_back(model);
    }
    else if (key == "-lm") {
      ++i;
      LM *model = new LM(argv[i]);
      ffVec.push_back(model);
    }
    else if (key == "-config") {
      ++i;
      iniPath = argv[i];
    }
  }

  Output();
}

std::vector<std::string> Tokenize(const std::string& str,
    const std::string& delimiters)
{
  std::vector<std::string> tokens;
  // Skip delimiters at beginning.
  std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
  // Find first "non-delimiter".
  std::string::size_type pos     = str.find_first_of(delimiters, lastPos);

  while (std::string::npos != pos || std::string::npos != lastPos) {
    // Found a token, add it to the vector.
    tokens.push_back(str.substr(lastPos, pos - lastPos));
    // Skip delimiters.  Note the "not_of"
    lastPos = str.find_first_not_of(delimiters, pos);
    // Find next "non-delimiter"
    pos = str.find_first_of(delimiters, lastPos);
  }

  return tokens;
}

<|endoftext|>