<commit_before>#include "lexer.h"

#include "token.h"

#include <cassert>
#include <iostream>
#include <sstream>

namespace ceos {

  std::shared_ptr<Token> Lexer::nextToken() {
    char c ;

    do {
      c = m_input.get();
    } while(isspace(c));

    switch (c) {
      case '(':
        m_token = std::make_shared<Token>(Token::Type::L_PAREN);
        break;

      case ')':
        m_token = std::make_shared<Token>(Token::Type::R_PAREN);
        break;

      case EOF:
        m_token = std::make_shared<Token>(Token::Type::END);
        break;

      case '#':
        do {
          c = m_input.get();
        } while (c != '\n');
        return nextToken();

      case '"': {
        std::stringstream str;
        while ((c = m_input.get()) != '"') {
          str.put(c);
        }
        m_token = std::make_shared<Token::String>(str.str());
      }

      case '\'': {
        int number = m_input.get();
        assert(m_input.get() == '\'');
        m_token = std::make_shared<Token::Number>(number);
      }

      default:
        if (isnumber(c)) {
          int number = 0;
          do {
            number *= 10;
            number += c - '0';
          } while (isnumber(c = m_input.get()));

          m_input.unget();

          m_token = std::make_shared<Token::Number>(number);
        } else if (isalpha(c)) {
          std::stringstream id;
          do {
            id << c;
          } while (isalpha(c = m_input.get()));

          m_input.unget();

          m_token = std::make_shared<Token::ID>(id.str());
        }
    }

    return m_token;
  }

  std::shared_ptr<Token> Lexer::token(Token::Type type) {
    auto token = m_token;
    ensure(type);
    return token;
  }

  std::shared_ptr<Token> Lexer::token(void) {
    return m_token;
  }

  void Lexer::ensure(Token::Type type) {
    assertType(m_token->type, type);
    nextToken();
  }

  void Lexer::assertType(Token::Type a, Token::Type b) {
    if (a != b) {
      std::cerr << "Invalid type found: expected `" << Token::typeName(a) << "` to be `" << Token::typeName(b) << "`" << "\n";
      throw "Parser error";
    }
  }

  void Lexer::invalidType(Token::Type type) {
    std::cerr << "Invalid type found: `" << Token::typeName(type) << "`\n";
    throw "Type error";
  }
}
<commit_msg>Fix missing break`s on switch statement<commit_after>#include "lexer.h"

#include "token.h"

#include <cassert>
#include <iostream>
#include <sstream>

namespace ceos {

  std::shared_ptr<Token> Lexer::nextToken() {
    char c ;

    do {
      c = m_input.get();
    } while(isspace(c));

    switch (c) {
      case '(':
        m_token = std::make_shared<Token>(Token::Type::L_PAREN);
        break;

      case ')':
        m_token = std::make_shared<Token>(Token::Type::R_PAREN);
        break;

      case EOF:
        m_token = std::make_shared<Token>(Token::Type::END);
        break;

      case '#':
        do {
          c = m_input.get();
        } while (c != '\n');
        return nextToken();

      case '"': {
        std::stringstream str;
        while ((c = m_input.get()) != '"') {
          str.put(c);
        }
        m_token = std::make_shared<Token::String>(str.str());
        break;
      }

      case '\'': {
        int number = m_input.get();
        assert(m_input.get() == '\'');
        m_token = std::make_shared<Token::Number>(number);
        break;
      }

      default:
        if (isnumber(c)) {
          int number = 0;
          do {
            number *= 10;
            number += c - '0';
          } while (isnumber(c = m_input.get()));

          m_input.unget();

          m_token = std::make_shared<Token::Number>(number);
        } else if (isalpha(c)) {
          std::stringstream id;
          do {
            id << c;
          } while (isalpha(c = m_input.get()));

          m_input.unget();

          m_token = std::make_shared<Token::ID>(id.str());
        }
    }

    return m_token;
  }

  std::shared_ptr<Token> Lexer::token(Token::Type type) {
    auto token = m_token;
    ensure(type);
    return token;
  }

  std::shared_ptr<Token> Lexer::token(void) {
    return m_token;
  }

  void Lexer::ensure(Token::Type type) {
    assertType(m_token->type, type);
    nextToken();
  }

  void Lexer::assertType(Token::Type a, Token::Type b) {
    if (a != b) {
      std::cerr << "Invalid type found: expected `" << Token::typeName(a) << "` to be `" << Token::typeName(b) << "`" << "\n";
      throw "Parser error";
    }
  }

  void Lexer::invalidType(Token::Type type) {
    std::cerr << "Invalid type found: `" << Token::typeName(type) << "`\n";
    throw "Type error";
  }
}
<|endoftext|>


<commit_before>#include<iostream>
#include<math.h>
#include<stdlib.h>

int prime[10000],primes;

//generate all the primes between 0 and sqrt(10000)
void init_primes(){
     static bool isprime[32000];
     int i,j;
     for(i=2;i<32000;i++) isprime[i]=true;
     for(i=2;i*i < 32000;i++)if(isprime[i])
     {
         for(j=2*i;j<32000;j+=i) isprime[j]=false;
     }
     primes=0;
     for(i=2;i<32000;i++)
        if(isprime[i])
            prime[primes++]=i;
}

bool seive[100001];

void find_seive(int lo, int hi){
   int i,j,p,n;
   for(i=0; i<=hi-lo; i++)
       seive[i]=true;
   for(j=0;j<=primes;j++){
       p=prime[j];
       if(p*p > hi) break; //stop when the max prime is reached
       n = (lo/p)*p; //nearest compasite to the prime number p
       if(n<lo) n+=p;
       if(n==p) n+=p;
       for(;n<=hi; n+=p)
          seive[n-lo]=false;
   }
}

void generatePrimeBetween(const int lower, const int upper){
	if(lower<2) lower=2;
	find_seive(lower,upper);
        for(i=0; i<=upper-lower; i++)
            if(seive[i]){
               cout << lower+i << endl;
            }
}
int main(){
	// your code goes here
	init_primes();
	int noOfTestCases;
	scanf("%d", &noOfTestCases);
	int num1; //smaller number
	int num2; // larger number
	while (noOfTestCases--) {
		scanf("%d %d",&num1,&num2);
		generatePrimeBetween(num1, num2);
		cout << endl;
	}
	return 0;
}
<commit_msg>Update main.cpp<commit_after>#include<iostream>
#include<math.h>
#include<stdlib.h>

int prime[10000],primes;

//generate all the primes between 0 and sqrt(10000)
void init_primes(){
     static bool isprime[32000];
     int i,j;
     for(i=2;i<32000;i++) isprime[i]=true;
     for(i=2;i*i < 32000;i++)if(isprime[i])
     {
         for(j=2*i;j<32000;j+=i) isprime[j]=false;
     }
     primes=0;
     for(i=2;i<32000;i++)
        if(isprime[i])
            prime[primes++]=i;
}

bool seive[100001];

void find_seive(int lo, int hi){
   int i,j,p,n;
   for(i=0; i<=hi-lo; i++)
       seive[i]=true;
   for(j=0;j<=primes;j++){
       p=prime[j];
       if(p*p > hi) break; //stop when the max prime is reached
       n = (lo/p)*p; //nearest compasite to the prime number p
       if(n<lo) n+=p;
       if(n==p) n+=p;
       for(;n<=hi; n+=p)
          seive[n-lo]=false;
   }
}

void generatePrimeBetween(const int lower, const int upper){
	if(lower<2) lower=2;
	find_seive(lower,upper);
        for(i=0; i<=upper-lower; i++)
            if(seive[i]){
               cout << lower+i << endl;
            }
}
int main(){
	init_primes();
	int noOfTestCases;
	scanf("%d", &noOfTestCases);
	int num1; //smaller number
	int num2; // larger number
	while (noOfTestCases--) {
		scanf("%d %d",&num1,&num2);
		generatePrimeBetween(num1, num2);
		cout << endl;
	}
	return 0;
}
<|endoftext|>


<commit_before>/*
Udp NTP Client
Get the time from a Network Time Protocol (NTP) time server
Demonstrates use of UDP sendPacket and ReceivePacket
For more on NTP time servers and the messages needed to communicate with them,
see http://en.wikipedia.org/wiki/Network_Time_Protocol

created 4 Sep 2010
by Michael Margolis

modified 17 Sep 2010
by Tom Igoe

modified 4 feb 2015
by Guus Beckett, Jim van Abkoude & Julian West
This code is in the public domain.
*/
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Dns.h>
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] =
{
    0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
unsigned int localPort = 8888; // local port to listen for UDP packets
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
const int button1 = 8;     // the number of the pushbutton pin
const int button2 = 7;     // the number of the pushbutton pin
void hue(int switcher)
{
    EthernetClient client;

    IPAddress server(192,168,1,2);

    if(client.connect(server,80))
    {
        client.println("PUT /api/newdeveloper/lights/4/state HTTP/1.1");
        // client.println("GET /api/newdeveloper/lights/4 HTTP/1.1");
        client.println("Host: 192.168.1.2");
        client.println("Connection: keep-alive");
        client.println("Content-Type:   text/plain; charset=UTF-8");
        if (switcher)
        {
            client.println("Content-Length: 11");
            client.println("");
            Serial.println("Sending ON:true");
            client.println("{\"on\":true}");
        }
        else
        {
            client.println("Content-Length: 12");
            client.println("");
            Serial.println("Sending ON:false");
            client.println("{\"on\":false}");
        }
        client.println("");
        Serial.println("Klaar");
        while (!client.available())
        {
            delay(1);
        }
        while (client.available()) {
            char c = client.read();
            Serial.print(c);
        }
    }
    else
    {
        Serial.println("Can\'t connect");
    }
}
void setup()
{
    Serial.begin(9600);
    Serial.println("Starting up");
    // start Ethernet and UDP
    if (Ethernet.begin(mac) == 0)
    {
        Serial.println("Failed to configure Ethernet using DHCP");
        // no point in carrying on, so do nothing forevermore:
        for (;;);
    }
else
{

    Serial.print("Local IP: ");
    Serial.println(Ethernet.localIP());
    Serial.print("Subnet Mask: ");
    Serial.println(Ethernet.subnetMask());
    Serial.print("Gateway: ");
    Serial.println(Ethernet.gatewayIP());
    Serial.print("Primary DNS: ");
    Serial.println(Ethernet.dnsServerIP());
}
DNSClient client;
client.begin(Ethernet.dnsServerIP());
pinMode(button1, INPUT);
pinMode(button2, INPUT);

}
void loop()
{
    int onOffSwitch = -1;
    int buttonState1 = digitalRead(button1);
    int buttonState2 = digitalRead(button2);

    if (buttonState1 == HIGH) {
    // turn LED on:
        Serial.println("ON");
        onOffSwitch = 1;

    }
    if (buttonState2 == HIGH) {
    // turn LED on:
        Serial.println("OFF");
        onOffSwitch = 0;
    }
    // wait ten seconds before asking for the time again
    if (onOffSwitch!=-1)
    {
      /* code */
        hue(onOffSwitch);
    }
    delay(1000);
}

<commit_msg>Improved code by adding delay after sending on/off request<commit_after>/*
Udp NTP Client
Get the time from a Network Time Protocol (NTP) time server
Demonstrates use of UDP sendPacket and ReceivePacket
For more on NTP time servers and the messages needed to communicate with them,
see http://en.wikipedia.org/wiki/Network_Time_Protocol

created 4 Sep 2010
by Michael Margolis

modified 17 Sep 2010
by Tom Igoe

modified 4 feb 2015
by Guus Beckett, Jim van Abkoude & Julian West
This code is in the public domain.
*/
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Dns.h>
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] =
{
    0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
unsigned int localPort = 8888; // local port to listen for UDP packets
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
const int button1 = 8;     // the number of the pushbutton pin
const int button2 = 7;     // the number of the pushbutton pin
void hue(int switcher)
{
    EthernetClient client;

    IPAddress server(192,168,1,2);

    if(client.connect(server,80))
    {
        client.println("PUT /api/newdeveloper/lights/4/state HTTP/1.1");
        // client.println("GET /api/newdeveloper/lights/4 HTTP/1.1");
        client.println("Host: 192.168.1.2");
        client.println("Connection: keep-alive");
        client.println("Content-Type:   text/plain; charset=UTF-8");
        if (switcher)
        {
            client.println("Content-Length: 11");
            client.println("");
            Serial.println("Sending ON:true");
            client.println("{\"on\":true}");
        }
        else
        {
            client.println("Content-Length: 12");
            client.println("");
            Serial.println("Sending ON:false");
            client.println("{\"on\":false}");
        }
        client.println("");
        Serial.println("Klaar");
        while (!client.available())
        {
            delay(1);
        }
        while (client.available()) {
            char c = client.read();
            Serial.print(c);
        }
    }
    else
    {
        Serial.println("Can\'t connect");
    }
}
void setup()
{
    Serial.begin(9600);
    Serial.println("Starting up");
    // start Ethernet and UDP
    if (Ethernet.begin(mac) == 0)
    {
        Serial.println("Failed to configure Ethernet using DHCP");
        // no point in carrying on, so do nothing forevermore:
        for (;;);
    }
else
{

    Serial.print("Local IP: ");
    Serial.println(Ethernet.localIP());
    Serial.print("Subnet Mask: ");
    Serial.println(Ethernet.subnetMask());
    Serial.print("Gateway: ");
    Serial.println(Ethernet.gatewayIP());
    Serial.print("Primary DNS: ");
    Serial.println(Ethernet.dnsServerIP());
}
DNSClient client;
client.begin(Ethernet.dnsServerIP());
pinMode(button1, INPUT);
pinMode(button2, INPUT);

}
void loop()
{
    int onOffSwitch = -1;
    int buttonState1 = digitalRead(button1);
    int buttonState2 = digitalRead(button2);

    if (buttonState1 == HIGH) {
    // turn LED on:
        Serial.println("ON");
        onOffSwitch = 1;

    }
    if (buttonState2 == HIGH) {
    // turn LED on:
        Serial.println("OFF");
        onOffSwitch = 0;
    }
    // wait ten seconds before asking for the time again
    if (onOffSwitch!=-1)
    {
      /* code */
        hue(onOffSwitch);
        delay(1000);
    }
    delay(10);
}

<|endoftext|>


<commit_before>/**
 * \file SinusGeneratorFilter.cpp
 */

#include "SinusGeneratorFilter.h"

#include <cmath>

#include <boost/math/constants/constants.hpp>

namespace ATK
{
  template<typename DataType_>
  SinusGeneratorFilter<DataType_>::SinusGeneratorFilter()
  :Parent(0, 2), volume(1), offset(0), frequency(0), frequ_cos(1), frequ_sin(0), cos(1), sin(0)
  {
  }

  template<typename DataType_>
  SinusGeneratorFilter<DataType_>::~SinusGeneratorFilter()
  {
  }

  template<typename DataType_>
  void SinusGeneratorFilter<DataType_>::set_frequency(DataType_ frequency)
  {
    this->frequency = frequency;
    this->frequ_cos = std::cos(2 * boost::math::constants::pi<DataType_>() * frequency / output_sampling_rate);
    this->frequ_sin = std::sin(2 * boost::math::constants::pi<DataType_>() * frequency / output_sampling_rate);
    setup();
  }

  template<typename DataType_>
  DataType_ SinusGeneratorFilter<DataType_>::get_frequency() const
  {
    return frequency;
  }

  template<typename DataType_>
  void SinusGeneratorFilter<DataType_>::set_volume(double volume)
  {
    this->volume = volume;
  }

  template<typename DataType_>
  double SinusGeneratorFilter<DataType_>::get_volume() const
  {
    return volume;
  }

  template<typename DataType_>
  void SinusGeneratorFilter<DataType_>::set_offset(double offset)
  {
    this->offset = offset;
  }

  template<typename DataType_>
  double SinusGeneratorFilter<DataType_>::get_offset() const
  {
    return offset;
  }

  template<typename DataType_>
  void SinusGeneratorFilter<DataType_>::full_setup()
  {
    Parent::full_setup();
    cos = 1;
    sin = 0;
  }

  template<typename DataType_>
  void SinusGeneratorFilter<DataType_>::process_impl(int64_t size) const
  {
    DataType* ATK_RESTRICT output_cos = outputs[0];
    DataType* ATK_RESTRICT output_sin = outputs[1];

    for(int64_t i = 0; i < size; ++i)
    {
      auto new_cos = cos * frequ_cos - sin * frequ_sin;
      auto new_sin = cos * frequ_sin + sin * frequ_cos;

      cos = new_cos / (new_cos * new_cos + new_sin * new_sin);
      sin = new_sin / (new_cos * new_cos + new_sin * new_sin);

      output_cos[i] = volume * cos + offset;
      output_sin[i] = volume * sin + offset;
    }
  }

  template class SinusGeneratorFilter<float>;
  template class SinusGeneratorFilter<double>;
}
<commit_msg>Compilation error on Linux<commit_after>/**
 * \file SinusGeneratorFilter.cpp
 */

#include "SinusGeneratorFilter.h"

#include <cmath>

#include <boost/math/constants/constants.hpp>

namespace ATK
{
  template<typename DataType_>
  SinusGeneratorFilter<DataType_>::SinusGeneratorFilter()
  :Parent(0, 2), volume(1), offset(0), frequency(0), frequ_cos(1), frequ_sin(0), cos(1), sin(0)
  {
  }

  template<typename DataType_>
  SinusGeneratorFilter<DataType_>::~SinusGeneratorFilter()
  {
  }

  template<typename DataType_>
  void SinusGeneratorFilter<DataType_>::set_frequency(DataType_ frequency)
  {
    this->frequency = frequency;
    this->frequ_cos = std::cos(2 * boost::math::constants::pi<DataType_>() * frequency / output_sampling_rate);
    this->frequ_sin = std::sin(2 * boost::math::constants::pi<DataType_>() * frequency / output_sampling_rate);
    Parent::setup();
  }

  template<typename DataType_>
  DataType_ SinusGeneratorFilter<DataType_>::get_frequency() const
  {
    return frequency;
  }

  template<typename DataType_>
  void SinusGeneratorFilter<DataType_>::set_volume(double volume)
  {
    this->volume = volume;
  }

  template<typename DataType_>
  double SinusGeneratorFilter<DataType_>::get_volume() const
  {
    return volume;
  }

  template<typename DataType_>
  void SinusGeneratorFilter<DataType_>::set_offset(double offset)
  {
    this->offset = offset;
  }

  template<typename DataType_>
  double SinusGeneratorFilter<DataType_>::get_offset() const
  {
    return offset;
  }

  template<typename DataType_>
  void SinusGeneratorFilter<DataType_>::full_setup()
  {
    Parent::full_setup();
    cos = 1;
    sin = 0;
  }

  template<typename DataType_>
  void SinusGeneratorFilter<DataType_>::process_impl(int64_t size) const
  {
    DataType* ATK_RESTRICT output_cos = outputs[0];
    DataType* ATK_RESTRICT output_sin = outputs[1];

    for(int64_t i = 0; i < size; ++i)
    {
      auto new_cos = cos * frequ_cos - sin * frequ_sin;
      auto new_sin = cos * frequ_sin + sin * frequ_cos;

      cos = new_cos / (new_cos * new_cos + new_sin * new_sin);
      sin = new_sin / (new_cos * new_cos + new_sin * new_sin);

      output_cos[i] = volume * cos + offset;
      output_sin[i] = volume * sin + offset;
    }
  }

  template class SinusGeneratorFilter<float>;
  template class SinusGeneratorFilter<double>;
}
<|endoftext|>


<commit_before>/******************************************************************************
 * BRICS_3D - 3D Perception and Modeling Library
 * Copyright (c) 2014, KU Leuven
 *
 * Author: Sebastian Blumenthal
 *
 *
 * This software is published under a dual-license: GNU Lesser General Public
 * License LGPL 2.1 and Modified BSD license. The dual-license implies that
 * users of this code may choose which terms they prefer.
 *
 * 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 Lesser General Public License LGPL and the BSD license for
 * more details.
 *
 ******************************************************************************/

#include "HDF5UpdateDeserializer.h"
#include "brics_3d/core/HomogeneousMatrix44.h"
#include <fstream>
#include "H5LTpublic.h" // not in default installation -> need to enable HDF5_BUILD_HLIB

namespace brics_3d {
namespace rsg {

// helper struct to memorize index and name vector
typedef struct {
    int index;               // index of the current object
    std::vector<std::string> collectedGroupNames;
} group_name_iter_info;

herr_t collectGroupNames(hid_t loc_id, const char *name, void *opdata) {
	LOG(DEBUG) << "H5::Group name = " << name;

	group_name_iter_info *info=(group_name_iter_info *)opdata;
    int obj_type = H5Gget_objtype_by_idx(loc_id, info->index);
    if(obj_type == H5G_GROUP) {
    	 LOG(DEBUG)  << "        is a group";
    		info->collectedGroupNames.push_back(name);

    } else {
		LOG(DEBUG) << "       is NOT a proup but of type: " << obj_type;
	}

    (info->index)++;
    return 0;
}

HDF5UpdateDeserializer::HDF5UpdateDeserializer(WorldModel* wm) :
		wm(wm) {

}

HDF5UpdateDeserializer::~HDF5UpdateDeserializer() {

}

int HDF5UpdateDeserializer::write(const char* dataBuffer, int dataLength,
		int& transferredBytes) {

	bool result = handleSceneGraphUpdate(dataBuffer, dataLength, transferredBytes);
	return result;

}

bool HDF5UpdateDeserializer::handleSceneGraphUpdate(const char* dataBuffer,
		int dataLength, int& transferredBytes) {

	LOG(DEBUG) << "HDF5UpdateDeserializer: Receiving a new data stream.";

	/* safe as tmp file  */
	std::string messageName = "tmpMessage.h5";
//	std::ofstream outputFile(messageName.c_str(), std::ios::binary | std::ios::trunc);
//	outputFile.write(dataBuffer, dataLength);
//	outputFile.flush();
//	outputFile.close();

	/* open with HDF5 */
    try {

    	/* Create HDF5 (in-memory) image file from data buffer */
    	unsigned flags;
    	flags = H5LT_FILE_IMAGE_DONT_COPY | H5LT_FILE_IMAGE_DONT_RELEASE;
//    	flags = H5LT_FILE_IMAGE_DONT_COPY;
    	LOG(DEBUG) << "HDF5UpdateDeserializer: trying H5LTopen_file_image.";
    	hid_t fileId = H5LTopen_file_image((char* )dataBuffer, dataLength, flags); // to copy or not?
    	LOG(DEBUG) << "HDF5UpdateDeserializer: H5LTopen_file_image done.";
    	H5::H5File file;
    	file.setId(fileId);
    	LOG(DEBUG) << "HDF5UpdateDeserializer: HDF5 file set up.";

       //H5::Exception::dontPrint();
//    	H5::H5File file(messageName, H5F_ACC_RDONLY); // re-open that tmp file

       H5::Group scene = file.openGroup("Scene");
       LOG(DEBUG) << "HDF5UpdateDeserializer: Opened \"Scene\" group.";
       HDF5Typecaster::RsgUpdateCommand command;
       HDF5Typecaster::RsgNodeTypeInfo type;
       HDF5Typecaster::getCommandTypeInfoFromHDF5Group(command, scene);
       bool hasParentId = false;

       /* Discover the attached HDF5 groups */
       group_name_iter_info groupNamesIterator;
       groupNamesIterator.index = 0;
       scene.iterateElems(".", NULL, collectGroupNames, &groupNamesIterator);
       std::vector<std::string> groupNames = groupNamesIterator.collectedGroupNames;
       if(groupNames.size() != 1) {
    	   LOG(ERROR) << "HDF5UpdateDeserializer:  Discovered " << groupNames.size() << " H5::Groups underneath Scene Group. Should be one.";
    	   file.close();
    	   return false;
       }
       std::string groupName = groupNames[0];
       LOG(DEBUG) << "Opening H5::Group with name " << groupName;
       H5::Group group = scene.openGroup(groupName);

       /* parse incoming data */
       switch (command) {

		   case HDF5Typecaster::ADD:

			   LOG(DEBUG) << "HDF5UpdateDeserializer: Processing ADD command";
		       try {
		    	   HDF5Typecaster::getNodeIdFromHDF5Group(parentId, scene, rsgParentIdName); // we memorize the parent Id as backtrack in HDF5 is not so easy.
		    	   hasParentId = true;
		       } catch (H5::Exception e) {
		    	   LOG(WARNING) << "No parentId given.";
		       }

			   if(!hasParentId) {
				   LOG(ERROR) << "Retrieved an ADD command, but without parentId - this does not work.";
				   break;

			   }
			   HDF5Typecaster::getNodeTypeInfoFromHDF5Group(type, group);

			   switch (type) {
			   case HDF5Typecaster::NODE:
				   doAddNode(group);
				   break;

			   case HDF5Typecaster::GROUP:
				   doAddGroup(group);
				   break;

			   case HDF5Typecaster::GEOMETIRC_NODE:
				   LOG(DEBUG) << "entering doAddGeometricNode(group)";
				   doAddGeometricNode(group);
				   break;

			   case HDF5Typecaster::TRANSFORM:
				   doAddTransformNode(group);
				   break;

			   default:
				   LOG(WARNING) << "HDF5UpdateDeserializer: Unhandled node type: " << type;
				   break;
			   }
			   break;

           case HDF5Typecaster::SET_TRANSFORM:

        	   LOG(DEBUG) << "HDF5UpdateDeserializer: Processing SET_TRANSFOR command";
        	   HDF5Typecaster::getNodeTypeInfoFromHDF5Group(type, group);
        	   if(type != HDF5Typecaster::TRANSFORM) {
        		   LOG(ERROR) << "Received a SET_TRANSFORM command, but node type is not a Transform.";
        		   return false;
        	   }
        	   doSetTransform(group);

        	   break;

           case HDF5Typecaster::DELETE:

        	   LOG(DEBUG) << "HDF5UpdateDeserializer: Processing DELETE command";
        	   doDeleteNode(group);

        	   break;

    	   break;
    	   default:
    		   LOG(WARNING) << "HDF5UpdateDeserializer: Unhandled command: " << command;
    		   break;

       }

       /* close file */
       file.flush(H5F_SCOPE_GLOBAL);
       file.close();

    } catch (H5::Exception e) {
    	LOG(ERROR) << "HDF5UpdateDeserializer: cannot process HDF5 file " << messageName;
    	return false;
    }

    transferredBytes = dataLength;
	return true;
}

bool HDF5UpdateDeserializer::doAddNode(H5::Group& group) {
	LOG(DEBUG) << "HDF5UpdateDeserializer: doAddNode.";
	Id id = 0;
	vector<Attribute> attributes;

	if (!HDF5Typecaster::getNodeIdFromHDF5Group(id, group)) {
		LOG(ERROR) << "H5::Group has no ID";
		return false;
	}
	LOG(DEBUG) << "H5::Group has ID " << id;
	HDF5Typecaster::getAttributesFromHDF5Group(attributes, group);

	return wm->scene.addNode(parentId, id, attributes, true);
}

bool HDF5UpdateDeserializer::doAddGroup(H5::Group& group) {
	LOG(DEBUG) << "HDF5UpdateDeserializer: doAddGroup.";
	Id id = 0;
	vector<Attribute> attributes;

	if (!HDF5Typecaster::getNodeIdFromHDF5Group(id, group)) {
		LOG(ERROR) << "H5::Group has no ID";
		return false;
	}
	LOG(DEBUG) << "H5::Group has ID " << id;
	HDF5Typecaster::getAttributesFromHDF5Group(attributes, group);

//	LOG(DEBUG) << "Complete group name = " << group.getObjnameByIdx(group.getId());

	return wm->scene.addGroup(parentId, id, attributes, true);
}

bool HDF5UpdateDeserializer::doAddTransformNode(H5::Group& group) {
	LOG(DEBUG) << "HDF5UpdateDeserializer: doAddTransformNode.";

	Id id = 0;
	vector<Attribute> attributes;
	IHomogeneousMatrix44::IHomogeneousMatrix44Ptr transform(new HomogeneousMatrix44());
	TimeStamp timeStamp;

	if (!HDF5Typecaster::getNodeIdFromHDF5Group(id, group)) {
		LOG(ERROR) << "H5::Group has no ID";
		return false;
	}
	LOG(DEBUG) << "H5::Group has ID " << id;
	HDF5Typecaster::getAttributesFromHDF5Group(attributes, group);

	if(!HDF5Typecaster::getTransformFromHDF5Group(transform, timeStamp, group)) {
		LOG(ERROR) << "H5::Group has no transform dataset.";
		return false;
	}
	LOG(DEBUG) << "Transform @t " << timeStamp.getSeconds() <<"  is" << std::endl << *transform;

	return wm->scene.addTransformNode(parentId, id, attributes, transform, timeStamp, true);
}

bool HDF5UpdateDeserializer::doAddGeometricNode(H5::Group& group) {
	LOG(INFO) << "HDF5UpdateDeserializer: doAddGeometricNode.";

	Id id = 0;
	vector<Attribute> attributes;
	Shape::ShapePtr shape;
	TimeStamp timeStamp;

	if (!HDF5Typecaster::getNodeIdFromHDF5Group(id, group)) {
		LOG(ERROR) << "H5::Group has no ID";
		return false;
	}
	LOG(DEBUG) << "H5::Group has ID " << id;
	HDF5Typecaster::getAttributesFromHDF5Group(attributes, group);

	if(!brics_3d::rsg::HDF5Typecaster::getShapeFromHDF5Group(shape, group)) {
		LOG(ERROR) << "H5::Group has no Shape";
		return false;
	}

	if(!brics_3d::rsg::HDF5Typecaster::getTimeStampFromHDF5Group(timeStamp, group)) {
		LOG(ERROR) << "H5::Group has no TimeStamp";
		return false;
	}

	return wm->scene.addGeometricNode(parentId, id, attributes, shape, timeStamp, true);
}

bool HDF5UpdateDeserializer::doSetNodeAttributes(H5::Group& group) {
	LOG(ERROR) << "HDF5UpdateDeserializer: doSetNodeAttributes functionality not yet implemented.";
	return false;
}

bool HDF5UpdateDeserializer::doSetTransform(H5::Group& group) {
	LOG(DEBUG) << "HDF5UpdateDeserializer: doSetTransform.";

	Id id;
	IHomogeneousMatrix44::IHomogeneousMatrix44Ptr transform(new HomogeneousMatrix44());
	TimeStamp timeStamp;

	if (!HDF5Typecaster::getNodeIdFromHDF5Group(id, group)) {
		LOG(ERROR) << "H5::Group has no ID";
		return false;
	}

	if(!HDF5Typecaster::getTransformFromHDF5Group(transform, timeStamp, group)) {
		LOG(ERROR) << "H5::Group has no transform dataset.";
		return false;
	}

	return wm->scene.setTransform(id, transform, timeStamp);
}

bool HDF5UpdateDeserializer::doDeleteNode(H5::Group& group) {
	LOG(DEBUG) << "HDF5UpdateDeserializer: doDeleteNode.";

	Id id;
	if (!HDF5Typecaster::getNodeIdFromHDF5Group(id, group)) {
		LOG(ERROR) << "H5::Group that shall be deleted has no ID";
		return false;
	}

	return wm->scene.deleteNode(id);
}

bool HDF5UpdateDeserializer::doAddParent(H5::Group& group) {
	LOG(ERROR) << "HDF5UpdateDeserializer: doAddParent functionality not yet implemented.";
	return false;
}

bool HDF5UpdateDeserializer::doRemoveParent(H5::Group& group) {
	LOG(ERROR) << "HDF5UpdateDeserializer: doRemoveParent functionality not yet implemented.";
	return false;
}

} /* namespace rsg */
} /* namespace brics_3d */

/* EOF */
<commit_msg>Added addParent() to HDF5 serialization.<commit_after>/******************************************************************************
 * BRICS_3D - 3D Perception and Modeling Library
 * Copyright (c) 2014, KU Leuven
 *
 * Author: Sebastian Blumenthal
 *
 *
 * This software is published under a dual-license: GNU Lesser General Public
 * License LGPL 2.1 and Modified BSD license. The dual-license implies that
 * users of this code may choose which terms they prefer.
 *
 * 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 Lesser General Public License LGPL and the BSD license for
 * more details.
 *
 ******************************************************************************/

#include "HDF5UpdateDeserializer.h"
#include "brics_3d/core/HomogeneousMatrix44.h"
#include <fstream>
#include "H5LTpublic.h" // not in default installation -> need to enable HDF5_BUILD_HLIB

namespace brics_3d {
namespace rsg {

// helper struct to memorize index and name vector
typedef struct {
    int index;               // index of the current object
    std::vector<std::string> collectedGroupNames;
} group_name_iter_info;

herr_t collectGroupNames(hid_t loc_id, const char *name, void *opdata) {
	LOG(DEBUG) << "H5::Group name = " << name;

	group_name_iter_info *info=(group_name_iter_info *)opdata;
    int obj_type = H5Gget_objtype_by_idx(loc_id, info->index);
    if(obj_type == H5G_GROUP) {
    	 LOG(DEBUG)  << "        is a group";
    		info->collectedGroupNames.push_back(name);

    } else {
		LOG(DEBUG) << "       is NOT a proup but of type: " << obj_type;
	}

    (info->index)++;
    return 0;
}

HDF5UpdateDeserializer::HDF5UpdateDeserializer(WorldModel* wm) :
		wm(wm) {

}

HDF5UpdateDeserializer::~HDF5UpdateDeserializer() {

}

int HDF5UpdateDeserializer::write(const char* dataBuffer, int dataLength,
		int& transferredBytes) {

	bool result = handleSceneGraphUpdate(dataBuffer, dataLength, transferredBytes);
	return result;

}

bool HDF5UpdateDeserializer::handleSceneGraphUpdate(const char* dataBuffer,
		int dataLength, int& transferredBytes) {

	LOG(DEBUG) << "HDF5UpdateDeserializer: Receiving a new data stream.";

	/* safe as tmp file  */
	std::string messageName = "tmpMessage.h5";
//	std::ofstream outputFile(messageName.c_str(), std::ios::binary | std::ios::trunc);
//	outputFile.write(dataBuffer, dataLength);
//	outputFile.flush();
//	outputFile.close();

	/* open with HDF5 */
    try {

    	/* Create HDF5 (in-memory) image file from data buffer */
    	unsigned flags;
    	flags = H5LT_FILE_IMAGE_DONT_COPY | H5LT_FILE_IMAGE_DONT_RELEASE;
//    	flags = H5LT_FILE_IMAGE_DONT_COPY;
    	LOG(DEBUG) << "HDF5UpdateDeserializer: trying H5LTopen_file_image.";
    	hid_t fileId = H5LTopen_file_image((char* )dataBuffer, dataLength, flags); // to copy or not?
    	LOG(DEBUG) << "HDF5UpdateDeserializer: H5LTopen_file_image done.";
    	H5::H5File file;
    	file.setId(fileId);
    	LOG(DEBUG) << "HDF5UpdateDeserializer: HDF5 file set up.";

       //H5::Exception::dontPrint();
//    	H5::H5File file(messageName, H5F_ACC_RDONLY); // re-open that tmp file

       H5::Group scene = file.openGroup("Scene");
       LOG(DEBUG) << "HDF5UpdateDeserializer: Opened \"Scene\" group.";
       HDF5Typecaster::RsgUpdateCommand command;
       HDF5Typecaster::RsgNodeTypeInfo type;
       HDF5Typecaster::getCommandTypeInfoFromHDF5Group(command, scene);
       bool hasParentId = false;

       /* Discover the attached HDF5 groups */
       group_name_iter_info groupNamesIterator;
       groupNamesIterator.index = 0;
       scene.iterateElems(".", NULL, collectGroupNames, &groupNamesIterator);
       std::vector<std::string> groupNames = groupNamesIterator.collectedGroupNames;
       if(groupNames.size() != 1) {
    	   LOG(ERROR) << "HDF5UpdateDeserializer:  Discovered " << groupNames.size() << " H5::Groups underneath Scene Group. Should be one.";
    	   file.close();
    	   return false;
       }
       std::string groupName = groupNames[0];
       LOG(DEBUG) << "Opening H5::Group with name " << groupName;
       H5::Group group = scene.openGroup(groupName);

       /* parse incoming data */
       switch (command) {

		   case HDF5Typecaster::ADD:

			   LOG(DEBUG) << "HDF5UpdateDeserializer: Processing ADD command";
		       try {
		    	   HDF5Typecaster::getNodeIdFromHDF5Group(parentId, scene, rsgParentIdName); // we memorize the parent Id as backtrack in HDF5 is not so easy.
		    	   hasParentId = true;
		       } catch (H5::Exception e) {
		    	   LOG(WARNING) << "No parentId given.";
		       }

			   if(!hasParentId) {
				   LOG(ERROR) << "Retrieved an ADD command, but without parentId - this does not work.";
				   break;
			   }

			   HDF5Typecaster::getNodeTypeInfoFromHDF5Group(type, group);

			   switch (type) {
			   case HDF5Typecaster::NODE:
				   doAddNode(group);
				   break;

			   case HDF5Typecaster::GROUP:
				   doAddGroup(group);
				   break;

			   case HDF5Typecaster::GEOMETIRC_NODE:
				   LOG(DEBUG) << "entering doAddGeometricNode(group)";
				   doAddGeometricNode(group);
				   break;

			   case HDF5Typecaster::TRANSFORM:
				   doAddTransformNode(group);
				   break;

			   default:
				   LOG(WARNING) << "HDF5UpdateDeserializer: Unhandled node type: " << type;
				   break;
			   }
			   break;

           case HDF5Typecaster::SET_TRANSFORM:

        	   LOG(DEBUG) << "HDF5UpdateDeserializer: Processing SET_TRANSFORM command";
        	   HDF5Typecaster::getNodeTypeInfoFromHDF5Group(type, group);
        	   if(type != HDF5Typecaster::TRANSFORM) {
        		   LOG(ERROR) << "Received a SET_TRANSFORM command, but node type is not a Transform.";
        		   return false;
        	   }
        	   doSetTransform(group);

        	   break;

           case HDF5Typecaster::DELETE:

        	   LOG(DEBUG) << "HDF5UpdateDeserializer: Processing DELETE command";
        	   doDeleteNode(group);

        	   break;

    	   break;

           case HDF5Typecaster::ADD_PARENT:

			   LOG(DEBUG) << "HDF5UpdateDeserializer: Processing ADD_PARENT command";
		       try {
		    	   HDF5Typecaster::getNodeIdFromHDF5Group(parentId, scene, rsgParentIdName); // we memorize the parent Id as backtrack in HDF5 is not so easy.
		    	   hasParentId = true;
		       } catch (H5::Exception e) {
		    	   LOG(WARNING) << "No parentId given.";
		       }

			   if(!hasParentId) {
				   LOG(ERROR) << "Retrieved an ADD_PARENT command, but without parentId - this does not work.";
				   break;
			   }

        	   LOG(DEBUG) << "HDF5UpdateDeserializer: Processing ADD_PARENT command";
        	   doAddParent(group);

        	   break;

    	   break;

    	   default:
    		   LOG(WARNING) << "HDF5UpdateDeserializer: Unhandled command: " << command;
    		   break;

       }

       /* close file */
       file.flush(H5F_SCOPE_GLOBAL);
       file.close();

    } catch (H5::Exception e) {
    	LOG(ERROR) << "HDF5UpdateDeserializer: cannot process HDF5 file " << messageName;
    	return false;
    }

    transferredBytes = dataLength;
	return true;
}

bool HDF5UpdateDeserializer::doAddNode(H5::Group& group) {
	LOG(DEBUG) << "HDF5UpdateDeserializer: doAddNode.";
	Id id = 0;
	vector<Attribute> attributes;

	if (!HDF5Typecaster::getNodeIdFromHDF5Group(id, group)) {
		LOG(ERROR) << "H5::Group has no ID";
		return false;
	}
	LOG(DEBUG) << "H5::Group has ID " << id;
	HDF5Typecaster::getAttributesFromHDF5Group(attributes, group);

	return wm->scene.addNode(parentId, id, attributes, true);
}

bool HDF5UpdateDeserializer::doAddGroup(H5::Group& group) {
	LOG(DEBUG) << "HDF5UpdateDeserializer: doAddGroup.";
	Id id = 0;
	vector<Attribute> attributes;

	if (!HDF5Typecaster::getNodeIdFromHDF5Group(id, group)) {
		LOG(ERROR) << "H5::Group has no ID";
		return false;
	}
	LOG(DEBUG) << "H5::Group has ID " << id;
	HDF5Typecaster::getAttributesFromHDF5Group(attributes, group);

//	LOG(DEBUG) << "Complete group name = " << group.getObjnameByIdx(group.getId());

	return wm->scene.addGroup(parentId, id, attributes, true);
}

bool HDF5UpdateDeserializer::doAddTransformNode(H5::Group& group) {
	LOG(DEBUG) << "HDF5UpdateDeserializer: doAddTransformNode.";

	Id id = 0;
	vector<Attribute> attributes;
	IHomogeneousMatrix44::IHomogeneousMatrix44Ptr transform(new HomogeneousMatrix44());
	TimeStamp timeStamp;

	if (!HDF5Typecaster::getNodeIdFromHDF5Group(id, group)) {
		LOG(ERROR) << "H5::Group has no ID";
		return false;
	}
	LOG(DEBUG) << "H5::Group has ID " << id;
	HDF5Typecaster::getAttributesFromHDF5Group(attributes, group);

	if(!HDF5Typecaster::getTransformFromHDF5Group(transform, timeStamp, group)) {
		LOG(ERROR) << "H5::Group has no transform dataset.";
		return false;
	}
	LOG(DEBUG) << "Transform @t " << timeStamp.getSeconds() <<"  is" << std::endl << *transform;

	return wm->scene.addTransformNode(parentId, id, attributes, transform, timeStamp, true);
}

bool HDF5UpdateDeserializer::doAddGeometricNode(H5::Group& group) {
	LOG(INFO) << "HDF5UpdateDeserializer: doAddGeometricNode.";

	Id id = 0;
	vector<Attribute> attributes;
	Shape::ShapePtr shape;
	TimeStamp timeStamp;

	if (!HDF5Typecaster::getNodeIdFromHDF5Group(id, group)) {
		LOG(ERROR) << "H5::Group has no ID";
		return false;
	}
	LOG(DEBUG) << "H5::Group has ID " << id;
	HDF5Typecaster::getAttributesFromHDF5Group(attributes, group);

	if(!brics_3d::rsg::HDF5Typecaster::getShapeFromHDF5Group(shape, group)) {
		LOG(ERROR) << "H5::Group has no Shape";
		return false;
	}

	if(!brics_3d::rsg::HDF5Typecaster::getTimeStampFromHDF5Group(timeStamp, group)) {
		LOG(ERROR) << "H5::Group has no TimeStamp";
		return false;
	}

	return wm->scene.addGeometricNode(parentId, id, attributes, shape, timeStamp, true);
}

bool HDF5UpdateDeserializer::doSetNodeAttributes(H5::Group& group) {
	LOG(ERROR) << "HDF5UpdateDeserializer: doSetNodeAttributes functionality not yet implemented.";
	return false;
}

bool HDF5UpdateDeserializer::doSetTransform(H5::Group& group) {
	LOG(DEBUG) << "HDF5UpdateDeserializer: doSetTransform.";

	Id id;
	IHomogeneousMatrix44::IHomogeneousMatrix44Ptr transform(new HomogeneousMatrix44());
	TimeStamp timeStamp;

	if (!HDF5Typecaster::getNodeIdFromHDF5Group(id, group)) {
		LOG(ERROR) << "H5::Group has no ID";
		return false;
	}

	if(!HDF5Typecaster::getTransformFromHDF5Group(transform, timeStamp, group)) {
		LOG(ERROR) << "H5::Group has no transform dataset.";
		return false;
	}

	return wm->scene.setTransform(id, transform, timeStamp);
}

bool HDF5UpdateDeserializer::doDeleteNode(H5::Group& group) {
	LOG(DEBUG) << "HDF5UpdateDeserializer: doDeleteNode.";

	Id id;
	if (!HDF5Typecaster::getNodeIdFromHDF5Group(id, group)) {
		LOG(ERROR) << "H5::Group that shall be deleted has no ID";
		return false;
	}

	return wm->scene.deleteNode(id);
}

bool HDF5UpdateDeserializer::doAddParent(H5::Group& group) {
	LOG(DEBUG) << "HDF5UpdateDeserializer: doAddParent.";

	Id id;
	if (!HDF5Typecaster::getNodeIdFromHDF5Group(id, group)) {
		LOG(ERROR) << "H5::Group that shall be deleted has no ID";
		return false;
	}

	return wm->scene.addParent(id, parentId);
}

bool HDF5UpdateDeserializer::doRemoveParent(H5::Group& group) {
	LOG(ERROR) << "HDF5UpdateDeserializer: doRemoveParent functionality not yet implemented.";
	return false;
}

} /* namespace rsg */
} /* namespace brics_3d */

/* EOF */
<|endoftext|>


<commit_before>#include <iostream>
#include <map>
#include <memory>
#include <string>
#include <time.h>
#include <vector>

#include "aggregate_bandwidth.cpp"
#include "aggregate_bandwidth.hpp"
#include "bytes_object.hpp"
#include "log_results.hpp"
#include <derecho/conf/conf.hpp>
#include <derecho/core/derecho.hpp>
#include <derecho/mutils-serialization/SerializationSupport.hpp>
#include <derecho/persistent/Persistent.hpp>
#include "partial_senders_allocator.hpp"

using std::endl;
using test::Bytes;

/**
 * RPC Object with a single function that accepts a string
 */
class TestObject {
public:
    void fun(const std::string& words) {
    }

    void bytes_fun(const Bytes& bytes) {
    }

    bool finishing_call(int x) {
        return true;
    }

    REGISTER_RPC_FUNCTIONS(TestObject, ORDERED_TARGETS(fun, bytes_fun, finishing_call));
};

struct exp_result {
    int num_nodes;
    uint32_t num_sender_sel;
    long long unsigned int max_msg_size;
    unsigned int window_size;
    uint32_t count;
    double avg_msec;
    double avg_gbps;

    void print(std::ofstream& fout) {
        fout << num_nodes << " " << num_sender_sel << " "
             << max_msg_size << " " << window_size << " "
             << count << " "
             << avg_msec << " " << avg_gbps << endl;
    }
};

#define DEFAULT_PROC_NAME "typed_bw_test"

int main(int argc, char* argv[]) {
    int dashdash_pos = argc - 1;
    while(dashdash_pos > 0) {
        if(strcmp(argv[dashdash_pos], "--") == 0) {
            break;
        }
        dashdash_pos--;
    }

    if((argc - dashdash_pos) < 4) {
        std::cout << "Invalid command line arguments." << std::endl;
        std::cout << "USAGE: " << argv[0] << " [ derecho-config-list -- ] <num_nodes> <count> <num_senders_selector>[proc_name]" << std::endl;
        std::cout << "Note: proc_name sets the process's name as displayed in ps and pkill commands, default is " DEFAULT_PROC_NAME << std::endl;
        return -1;
    }

    derecho::Conf::initialize(argc, argv);

    const int num_nodes = std::stoi(argv[dashdash_pos + 1]);
    const uint64_t max_msg_size = derecho::getConfUInt64(CONF_SUBGROUP_DEFAULT_MAX_PAYLOAD_SIZE);
    const uint32_t count = std::stoi(argv[dashdash_pos + 2]);
    const uint32_t num_senders_selector = std::stoi(argv[dashdash_pos + 3]);

    // Convert this integer to a more readable enum value
    const PartialSendMode senders_mode = num_senders_selector == 0
                                                 ? PartialSendMode::ALL_SENDERS
                                                 : (num_senders_selector == 1
                                                            ? PartialSendMode::HALF_SENDERS
                                                            : PartialSendMode::ONE_SENDER);

    // Compute the total number of messages that should be delivered
    uint64_t total_num_messages = 0;
    switch(senders_mode) {
        case PartialSendMode::ALL_SENDERS:
            total_num_messages = count * num_nodes;
            break;
        case PartialSendMode::HALF_SENDERS:
            total_num_messages = count * (num_nodes / 2);
            break;
        case PartialSendMode::ONE_SENDER:
            total_num_messages = count;
            break;
    }

    // variable 'done' tracks the end of the test
    volatile bool done = false;
    // callback into the application code at each message delivery
    auto stability_callback = [&done,
                               total_num_messages,
                               num_delivered = 0u](uint32_t subgroup,
                                                   uint32_t sender_id,
                                                   long long int index,
                                                   std::optional<std::pair<char*, long long int>> data,
                                                   persistent::version_t ver) mutable {
        // Count the total number of messages delivered
        ++num_delivered;
        // Check for completion
        if(num_delivered == total_num_messages) {
            done = true;
        }
    };

    if(dashdash_pos + 4 < argc) {
        pthread_setname_np(pthread_self(), argv[dashdash_pos + 3]);
    } else {
        pthread_setname_np(pthread_self(), DEFAULT_PROC_NAME);
    }

    derecho::SubgroupInfo subgroup_info{[num_nodes](
                                                const std::vector<std::type_index>& subgroup_type_order,
                                                const std::unique_ptr<derecho::View>& prev_view, derecho::View& curr_view) {
        if(curr_view.num_members < num_nodes) {
            std::cout << "not enough members yet:" << curr_view.num_members << " < " << num_nodes << std::endl;
            throw derecho::subgroup_provisioning_exception();
        }
        derecho::subgroup_shard_layout_t subgroup_layout(1);

        std::vector<uint32_t> members(num_nodes);
        for(int i = 0; i < num_nodes; i++) {
            members[i] = i;
        }

        subgroup_layout[0].emplace_back(curr_view.make_subview(members));
        curr_view.next_unassigned_rank = std::max(curr_view.next_unassigned_rank, num_nodes);
        derecho::subgroup_allocation_map_t subgroup_allocation;
        subgroup_allocation.emplace(std::type_index(typeid(TestObject)), std::move(subgroup_layout));
        return subgroup_allocation;
    }};

    auto ba_factory = [](persistent::PersistentRegistry*, derecho::subgroup_id_t) { return std::make_unique<TestObject>(); };

    derecho::Group<TestObject> group(derecho::CallbackSet{stability_callback}, subgroup_info, {}, std::vector<derecho::view_upcall_t>{}, ba_factory);
    std::cout << "Finished constructing/joining Group" << std::endl;

    derecho::Replicated<TestObject>& handle = group.get_subgroup<TestObject>();
    //std::string str_1k(max_msg_size, 'x');
    char* bbuf = (char*)malloc(max_msg_size);
    bzero(bbuf, max_msg_size);
    Bytes bytes(bbuf, max_msg_size);

    struct timespec t1, t2;
    clock_gettime(CLOCK_REALTIME, &t1);

    // this function sends all the messages
    auto send_all = [&]() {
        for(uint i = 0; i < count; i++) {
        //handle.ordered_send<RPC_NAME(fun)>(str_1k);
        handle.ordered_send<RPC_NAME(bytes_fun)>(bytes);
    }
    };

    int node_rank = group.get_my_rank();

    if(senders_mode == PartialSendMode::ALL_SENDERS) {
        send_all();
    } else if(senders_mode == PartialSendMode::HALF_SENDERS) {
        if(node_rank > (num_nodes - 1) / 2) {
            send_all();
        }
    } else {
        if(node_rank == num_nodes - 1) {
            send_all();
        }
    }

    /*
    if(node_rank == 0) {
        derecho::rpc::QueryResults<bool> results = handle.ordered_send<RPC_NAME(finishing_call)>(0);
        std::cout << "waiting for response..." << std::endl;
#pragma GCC diagnostic ignored "-Wunused-variable"
        decltype(results)::ReplyMap& replies = results.get();
#pragma GCC diagnostic pop
    }
    */

    while(!done){
    }

    clock_gettime(CLOCK_REALTIME, &t2);
    free(bbuf);

    double thp_gbps;
    int64_t nsec = ((int64_t)t2.tv_sec - t1.tv_sec) * 1000000000 + t2.tv_nsec - t1.tv_nsec;

    if(senders_mode == PartialSendMode::ALL_SENDERS) {
        thp_gbps = ((double)count * max_msg_size * num_nodes) / nsec;
    } else if(senders_mode == PartialSendMode::HALF_SENDERS) {
        thp_gbps = ((double)count * max_msg_size * num_nodes/2) / nsec;
    } else {
        thp_gbps = ((double)count * max_msg_size) / nsec;
    }

    double msec = (double)nsec / 1000000;
    double thp_ops = ((double)count * 1000000000) / nsec;
    std::cout << "timespan:" << msec << " millisecond." << std::endl;
    std::cout << "throughput:" << thp_gbps << "GB/s." << std::endl;
    std::cout << "throughput:" << thp_ops << "ops." << std::endl;

    // aggregate bandwidth from all nodes
    std::pair<double, double> bw_laten(thp_gbps,msec);

    auto members_order = group.get_members();
    bw_laten = aggregate_bandwidth(members_order, members_order[node_rank], bw_laten);

    double avg_gbps = bw_laten.first;
    double avg_msec = bw_laten.second;

    if(node_rank == 0) {
        log_results(exp_result{num_nodes, num_senders_selector, max_msg_size,
                               derecho::getConfUInt32(CONF_SUBGROUP_DEFAULT_WINDOW_SIZE), count,
                               avg_msec, avg_gbps},
                    "data_derecho_typed_subgroup_bw");
    }

    group.barrier_sync();
    group.leave();
}
<commit_msg>a bug fix in typed subgroup bandwidth test size calculation<commit_after>#include <iostream>
#include <map>
#include <memory>
#include <string>
#include <time.h>
#include <vector>

#include "aggregate_bandwidth.cpp"
#include "aggregate_bandwidth.hpp"
#include "bytes_object.hpp"
#include "log_results.hpp"
#include <derecho/conf/conf.hpp>
#include <derecho/core/derecho.hpp>
#include <derecho/mutils-serialization/SerializationSupport.hpp>
#include <derecho/persistent/Persistent.hpp>
#include "partial_senders_allocator.hpp"

using std::endl;
using test::Bytes;

/**
 * RPC Object with a single function that accepts a string
 */
class TestObject {
public:
    void fun(const std::string& words) {
    }

    void bytes_fun(const Bytes& bytes) {
    }

    bool finishing_call(int x) {
        return true;
    }

    REGISTER_RPC_FUNCTIONS(TestObject, ORDERED_TARGETS(fun, bytes_fun, finishing_call));
};

struct exp_result {
    int num_nodes;
    uint32_t num_sender_sel;
    long long unsigned int max_msg_size;
    unsigned int window_size;
    uint32_t count;
    double avg_msec;
    double avg_gbps;

    void print(std::ofstream& fout) {
        fout << num_nodes << " " << num_sender_sel << " "
             << max_msg_size << " " << window_size << " "
             << count << " "
             << avg_msec << " " << avg_gbps << endl;
    }
};

#define DEFAULT_PROC_NAME "typed_bw_test"

int main(int argc, char* argv[]) {
    int dashdash_pos = argc - 1;
    while(dashdash_pos > 0) {
        if(strcmp(argv[dashdash_pos], "--") == 0) {
            break;
        }
        dashdash_pos--;
    }

    if((argc - dashdash_pos) < 4) {
        std::cout << "Invalid command line arguments." << std::endl;
        std::cout << "USAGE: " << argv[0] << " [ derecho-config-list -- ] <num_nodes> <count> <num_senders_selector>[proc_name]" << std::endl;
        std::cout << "Note: proc_name sets the process's name as displayed in ps and pkill commands, default is " DEFAULT_PROC_NAME << std::endl;
        return -1;
    }

    derecho::Conf::initialize(argc, argv);

    //The maximum number of bytes that can be sent to change_pers_bytes() is not quite MAX_PAYLOAD_SIZE.
    //The serialized Bytes object will include its size field as well as the actual buffer, and
    //the RPC function header contains an InvocationID (which is a size_t) as well as the header
    //fields defined by remote_invocation_utilites::header_space().
    const std::size_t rpc_header_size = sizeof(std::size_t) + sizeof(std::size_t)
                                        + derecho::remote_invocation_utilities::header_space();

    const int num_nodes = std::stoi(argv[dashdash_pos + 1]);
    const uint64_t max_msg_size = derecho::getConfUInt64(CONF_SUBGROUP_DEFAULT_MAX_PAYLOAD_SIZE) - rpc_header_size;
    const uint32_t count = std::stoi(argv[dashdash_pos + 2]);
    const uint32_t num_senders_selector = std::stoi(argv[dashdash_pos + 3]);

    // Convert this integer to a more readable enum value
    const PartialSendMode senders_mode = num_senders_selector == 0
                                                 ? PartialSendMode::ALL_SENDERS
                                                 : (num_senders_selector == 1
                                                            ? PartialSendMode::HALF_SENDERS
                                                            : PartialSendMode::ONE_SENDER);

    // Compute the total number of messages that should be delivered
    uint64_t total_num_messages = 0;
    switch(senders_mode) {
        case PartialSendMode::ALL_SENDERS:
            total_num_messages = count * num_nodes;
            break;
        case PartialSendMode::HALF_SENDERS:
            total_num_messages = count * (num_nodes / 2);
            break;
        case PartialSendMode::ONE_SENDER:
            total_num_messages = count;
            break;
    }

    // variable 'done' tracks the end of the test
    volatile bool done = false;
    // callback into the application code at each message delivery
    auto stability_callback = [&done,
                               total_num_messages,
                               num_delivered = 0u](uint32_t subgroup,
                                                   uint32_t sender_id,
                                                   long long int index,
                                                   std::optional<std::pair<char*, long long int>> data,
                                                   persistent::version_t ver) mutable {
        // Count the total number of messages delivered
        ++num_delivered;
        // Check for completion
        if(num_delivered == total_num_messages) {
            done = true;
        }
    };

    if(dashdash_pos + 4 < argc) {
        pthread_setname_np(pthread_self(), argv[dashdash_pos + 3]);
    } else {
        pthread_setname_np(pthread_self(), DEFAULT_PROC_NAME);
    }

    derecho::SubgroupInfo subgroup_info{[num_nodes](
                                                const std::vector<std::type_index>& subgroup_type_order,
                                                const std::unique_ptr<derecho::View>& prev_view, derecho::View& curr_view) {
        if(curr_view.num_members < num_nodes) {
            std::cout << "not enough members yet:" << curr_view.num_members << " < " << num_nodes << std::endl;
            throw derecho::subgroup_provisioning_exception();
        }
        derecho::subgroup_shard_layout_t subgroup_layout(1);

        std::vector<uint32_t> members(num_nodes);
        for(int i = 0; i < num_nodes; i++) {
            members[i] = i;
        }

        subgroup_layout[0].emplace_back(curr_view.make_subview(members));
        curr_view.next_unassigned_rank = std::max(curr_view.next_unassigned_rank, num_nodes);
        derecho::subgroup_allocation_map_t subgroup_allocation;
        subgroup_allocation.emplace(std::type_index(typeid(TestObject)), std::move(subgroup_layout));
        return subgroup_allocation;
    }};

    auto ba_factory = [](persistent::PersistentRegistry*, derecho::subgroup_id_t) { return std::make_unique<TestObject>(); };

    derecho::Group<TestObject> group(derecho::CallbackSet{stability_callback}, subgroup_info, {}, std::vector<derecho::view_upcall_t>{}, ba_factory);
    std::cout << "Finished constructing/joining Group" << std::endl;

    derecho::Replicated<TestObject>& handle = group.get_subgroup<TestObject>();
    //std::string str_1k(max_msg_size, 'x');
    char* bbuf = (char*)malloc(max_msg_size);
    bzero(bbuf, max_msg_size);
    Bytes bytes(bbuf, max_msg_size);

    struct timespec t1, t2;
    clock_gettime(CLOCK_REALTIME, &t1);

    // this function sends all the messages
    auto send_all = [&]() {
        for(uint i = 0; i < count; i++) {
        //handle.ordered_send<RPC_NAME(fun)>(str_1k);
        handle.ordered_send<RPC_NAME(bytes_fun)>(bytes);
    }
    };

    int node_rank = group.get_my_rank();

    if(senders_mode == PartialSendMode::ALL_SENDERS) {
        send_all();
    } else if(senders_mode == PartialSendMode::HALF_SENDERS) {
        if(node_rank > (num_nodes - 1) / 2) {
            send_all();
        }
    } else {
        if(node_rank == num_nodes - 1) {
            send_all();
        }
    }

    /*
    if(node_rank == 0) {
        derecho::rpc::QueryResults<bool> results = handle.ordered_send<RPC_NAME(finishing_call)>(0);
        std::cout << "waiting for response..." << std::endl;
#pragma GCC diagnostic ignored "-Wunused-variable"
        decltype(results)::ReplyMap& replies = results.get();
#pragma GCC diagnostic pop
    }
    */

    while(!done){
    }

    clock_gettime(CLOCK_REALTIME, &t2);
    free(bbuf);

    double thp_gbps;
    int64_t nsec = ((int64_t)t2.tv_sec - t1.tv_sec) * 1000000000 + t2.tv_nsec - t1.tv_nsec;

    if(senders_mode == PartialSendMode::ALL_SENDERS) {
        thp_gbps = ((double)count * max_msg_size * num_nodes) / nsec;
    } else if(senders_mode == PartialSendMode::HALF_SENDERS) {
        thp_gbps = ((double)count * max_msg_size * num_nodes/2) / nsec;
    } else {
        thp_gbps = ((double)count * max_msg_size) / nsec;
    }

    double msec = (double)nsec / 1000000;
    double thp_ops = ((double)count * 1000000000) / nsec;
    std::cout << "timespan:" << msec << " millisecond." << std::endl;
    std::cout << "throughput:" << thp_gbps << "GB/s." << std::endl;
    std::cout << "throughput:" << thp_ops << "ops." << std::endl;

    // aggregate bandwidth from all nodes
    std::pair<double, double> bw_laten(thp_gbps,msec);

    auto members_order = group.get_members();
    bw_laten = aggregate_bandwidth(members_order, members_order[node_rank], bw_laten);

    double avg_gbps = bw_laten.first;
    double avg_msec = bw_laten.second;

    if(node_rank == 0) {
        log_results(exp_result{num_nodes, num_senders_selector, max_msg_size,
                               derecho::getConfUInt32(CONF_SUBGROUP_DEFAULT_WINDOW_SIZE), count,
                               avg_msec, avg_gbps},
                    "data_derecho_typed_subgroup_bw");
    }

    group.barrier_sync();
    group.leave();
}
<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 2020/3/8 22:03:07
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::multiprecision::cpp_int;
using ll = long long;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1000000007LL};
// constexpr ll MOD{998244353LL}; // be careful
constexpr ll MAX_SIZE{3000010LL};
// constexpr ll MAX_SIZE{30000010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint &operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint &operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator<=(const Mint &a) const { return x <= a.x; }
  bool operator>(const Mint &a) const { return x > a.x; }
  bool operator>=(const Mint &a) const { return x >= a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  bool operator!=(const Mint &a) const { return !(*this == a); }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
template <typename T>
T gcd(T x, T y) { return y ? gcd(y, x % y) : x; }
template <typename T>
T lcm(T x, T y) { return x / gcd(x, y) * y; }
// ----- for C++17 -----
template <typename T>
int popcount(T x) // C++20
{
  int ans{0};
  while (x != 0)
  {
    ans += x & 1;
    x >>= 1;
  }
  return ans;
}
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1000000000000000LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
// ----- main() -----

using field = vector<vector<int>>;

class Solve
{
  int N, M;
  int R, C;
  vector<field> V;

public:
  Solve(int N, int M) : N{N}, M{M}
  {
    R = (1 << N) - 1;
    C = (1 << M) - 1;
    /*
    all();
    int maxi{max_score()};
    cerr << "maxi = " << maxi << endl;
    flush_score_ban(maxi);
    */
    if (R == 1 && C == 1)
    {
      cout << 1 << endl;
      return;
    }
    for (auto i = 0; i < R; ++i)
    {
      for (auto j = 0; j < C; ++j)
      {
        if (i == R / 2 && j == C / 2)
        {
          cout << 0;
        }
        else
        {
          cout << 1;
        }
      }
      cout << endl;
    }
  }

private:
  void all()
  {
    ll X{1LL << (R * C)};
    for (auto i = 0; i < X; ++i)
    {
      field ban(R, vector<int>(C, 0));
      for (auto j = 0; j < R * C; ++j)
      {
        if ((i >> j) & 1)
        {
          ban[j / C][j % C] = 1;
        }
      }
      V.push_back(ban);
    }
  }

  int score(field const &ban)
  {
    int ans{0};
    for (auto i = 0; i < R; ++i)
    {
      for (auto j = i + 1; j <= R; ++j)
      {
        for (auto k = 0; k < C; ++k)
        {
          for (auto l = k + 1; l <= C; ++l)
          {
            int t{0};
            for (auto a = i; a < j; ++a)
            {
              for (auto b = k; b < l; ++b)
              {
                t += ban[a][b];
              }
            }
            if (t % 2 == 1)
            {
              ++ans;
            }
          }
        }
      }
    }
    return ans;
  }

  int max_score()
  {
    int ans{0};
    for (auto const &ban : V)
    {
      ch_max(ans, score(ban));
    }
    return ans;
  }

  void flush_score_ban(int s)
  {
    for (auto const &ban : V)
    {
      if (score(ban) == s)
      {
        cerr << "----" << endl;
        for (auto i = 0; i < R; ++i)
        {
          for (auto j = 0; j < C; ++j)
          {
            cerr << ban[i][j];
          }
          cerr << endl;
        }
      }
    }
  }
};

int main()
{
  int N, M;
  cin >> N >> M;
  Solve solve(N, M);
}
<commit_msg>tried E.cpp to 'E'<commit_after>#define DEBUG 1
/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 2020/3/8 22:03:07
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::multiprecision::cpp_int;
using ll = long long;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1000000007LL};
// constexpr ll MOD{998244353LL}; // be careful
constexpr ll MAX_SIZE{3000010LL};
// constexpr ll MAX_SIZE{30000010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint &operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint &operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator<=(const Mint &a) const { return x <= a.x; }
  bool operator>(const Mint &a) const { return x > a.x; }
  bool operator>=(const Mint &a) const { return x >= a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  bool operator!=(const Mint &a) const { return !(*this == a); }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
template <typename T>
T gcd(T x, T y) { return y ? gcd(y, x % y) : x; }
template <typename T>
T lcm(T x, T y) { return x / gcd(x, y) * y; }
// ----- for C++17 -----
template <typename T>
int popcount(T x) // C++20
{
  int ans{0};
  while (x != 0)
  {
    ans += x & 1;
    x >>= 1;
  }
  return ans;
}
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1000000000000000LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
// ----- main() -----

using field = vector<vector<int>>;

class Solve
{
  int N, M;
  int R, C;
  vector<field> V;

public:
  Solve(int N, int M) : N{N}, M{M}
  {
    R = (1 << N) - 1;
    C = (1 << M) - 1;
    all();
    int maxi{max_score()};
    cerr << "maxi = " << maxi << endl;
    flush_score_ban(maxi);
    /*
    if (R == 1 && C == 1)
    {
      cout << 1 << endl;
      return;
    }
    for (auto i = 0; i < R; ++i)
    {
      for (auto j = 0; j < C; ++j)
      {
        if (i == R / 2 && j == C / 2)
        {
          cout << 0;
        }
        else
        {
          cout << 1;
        }
      }
      cout << endl;
    }
    */
  }

private:
  void all()
  {
    ll X{1LL << (R * C)};
    for (auto i = 0; i < X; ++i)
    {
      field ban(R, vector<int>(C, 0));
      for (auto j = 0; j < R * C; ++j)
      {
        if ((i >> j) & 1)
        {
          ban[j / C][j % C] = 1;
        }
      }
      V.push_back(ban);
    }
  }

  int score(field const &ban)
  {
    int ans{0};
    for (auto i = 0; i < R; ++i)
    {
      for (auto j = i + 1; j <= R; ++j)
      {
        for (auto k = 0; k < C; ++k)
        {
          for (auto l = k + 1; l <= C; ++l)
          {
            int t{0};
            for (auto a = i; a < j; ++a)
            {
              for (auto b = k; b < l; ++b)
              {
                t += ban[a][b];
              }
            }
            if (t % 2 == 1)
            {
              ++ans;
            }
          }
        }
      }
    }
    return ans;
  }

  int max_score()
  {
    int ans{0};
    for (auto const &ban : V)
    {
      ch_max(ans, score(ban));
    }
    return ans;
  }

  void flush_score_ban(int s)
  {
    for (auto const &ban : V)
    {
      if (score(ban) == s)
      {
        for (auto i = 0; i < R; ++i)
        {
          for (auto j = 0; j < C; ++j)
          {
            cout << ban[i][j];
          }
          cout << endl;
        }
        return;
      }
    }
  }
};

int main()
{
  int N, M;
  cin >> N >> M;
  Solve solve(N, M);
}
<|endoftext|>


<commit_before>/*============================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.

Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.

============================================================================*/

#include "mitkFillRegionTool.h"

// us
#include <usGetModuleContext.h>
#include <usModule.h>
#include <usModuleContext.h>
#include <usModuleResource.h>

namespace mitk
{
  MITK_TOOL_MACRO(MITKSEGMENTATION_EXPORT, FillRegionTool, "Fill tool");
}

const char **mitk::FillRegionTool::GetXPM() const
{
  return nullptr;
}

us::ModuleResource mitk::FillRegionTool::GetIconResource() const
{
  us::Module *module = us::GetModuleContext()->GetModule();
  us::ModuleResource resource = module->GetResource("Fill.svg");
  return resource;
}

us::ModuleResource mitk::FillRegionTool::GetCursorIconResource() const
{
  us::Module *module = us::GetModuleContext()->GetModule();
  us::ModuleResource resource = module->GetResource("Fill_Cursor.svg");
  return resource;
}

const char *mitk::FillRegionTool::GetName() const
{
  return "Fill";
}

void mitk::FillRegionTool::PrepareFilling(const Image* /*workingSlice*/, Point3D /*seedPoint*/)
{
  auto labelSetImage = dynamic_cast<const LabelSetImage*>(this->GetWorkingData());

  if (nullptr == labelSetImage) mitkThrow() << "Invalid state of FillRegionTool. Working image is not of correct type.";

  m_FillLabelValue = labelSetImage->GetActiveLabel()->GetValue();
  m_MergeStyle = MultiLabelSegmentation::MergeStyle::Merge;
};

<commit_msg>Source fill label value from active layer<commit_after>/*============================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.

Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.

============================================================================*/

#include "mitkFillRegionTool.h"

// us
#include <usGetModuleContext.h>
#include <usModule.h>
#include <usModuleContext.h>
#include <usModuleResource.h>

namespace mitk
{
  MITK_TOOL_MACRO(MITKSEGMENTATION_EXPORT, FillRegionTool, "Fill tool");
}

const char **mitk::FillRegionTool::GetXPM() const
{
  return nullptr;
}

us::ModuleResource mitk::FillRegionTool::GetIconResource() const
{
  us::Module *module = us::GetModuleContext()->GetModule();
  us::ModuleResource resource = module->GetResource("Fill.svg");
  return resource;
}

us::ModuleResource mitk::FillRegionTool::GetCursorIconResource() const
{
  us::Module *module = us::GetModuleContext()->GetModule();
  us::ModuleResource resource = module->GetResource("Fill_Cursor.svg");
  return resource;
}

const char *mitk::FillRegionTool::GetName() const
{
  return "Fill";
}

void mitk::FillRegionTool::PrepareFilling(const Image* /*workingSlice*/, Point3D /*seedPoint*/)
{
  auto labelSetImage = dynamic_cast<const LabelSetImage*>(this->GetWorkingData());

  if (nullptr == labelSetImage) mitkThrow() << "Invalid state of FillRegionTool. Working image is not of correct type.";

  m_FillLabelValue = labelSetImage->GetActiveLabel(labelSetImage->GetActiveLayer())->GetValue();
  m_MergeStyle = MultiLabelSegmentation::MergeStyle::Merge;
};

<|endoftext|>


<commit_before>#include "VolumeSlider.h"

#include "..\Error.h"
#include "..\Skin.h"
#include "SliderKnob.h"

VolumeSlider::VolumeSlider(CoreAudio &volCtrl) :
OSD(L"3RVX-VolumeSlider"),
_sWnd(L"3RVX-VolumeSliderWnd", L"3RVX Volume Slider"),
_volCtrl(volCtrl) {

    Skin *skin = _settings.CurrentSkin();

    Gdiplus::Bitmap *bg = skin->ControllerBgImg("volume");
    _sWnd.BackgroundImage(bg);

    std::list<Meter*> meters = skin->Meters("volume");
    for (Meter *m : meters) {
        _sWnd.AddMeter(m);
    }

    _knob = skin->Knob("volume");
    _sWnd.Knob(_knob);

    _knob->Value(0.5f);

    _sWnd.Update();
    _sWnd.Show();
}

void VolumeSlider::Hide() {
    _visible = false;
    _sWnd.Hide(false);
}

bool VolumeSlider::Visible() {
    return _visible;
}<commit_msg>Add Show() method<commit_after>#include "VolumeSlider.h"

#include "..\Error.h"
#include "..\Skin.h"
#include "SliderKnob.h"

VolumeSlider::VolumeSlider(CoreAudio &volCtrl) :
OSD(L"3RVX-VolumeSlider"),
_sWnd(L"3RVX-VolumeSliderWnd", L"3RVX Volume Slider"),
_volCtrl(volCtrl) {

    Skin *skin = _settings.CurrentSkin();

    Gdiplus::Bitmap *bg = skin->ControllerBgImg("volume");
    _sWnd.BackgroundImage(bg);

    std::list<Meter*> meters = skin->Meters("volume");
    for (Meter *m : meters) {
        _sWnd.AddMeter(m);
    }

    _knob = skin->Knob("volume");
    _sWnd.Knob(_knob);

    _knob->Value(0.5f);

    _sWnd.Update();
    _sWnd.Show();
}

void VolumeSlider::Hide() {
    _visible = false;
    _sWnd.Hide(false);
}

void VolumeSlider::Show() {
    MeterWnd::MeterLevels(_level);
    Update();
    SliderWnd::Show();
}

bool VolumeSlider::Visible() {
    return _visible;
}<|endoftext|>


<commit_before><commit_msg>554 solved<commit_after><|endoftext|>


<commit_before>/* FILE: yy_stagemel.cc                 -*-Mode: c++-*-
 *
 * OOMMF magnetoelastic coupling extension module.
 * YY_StageMEL class.
 * Calculates MEL field/energy for each stage.
 *
 */

#include "oc.h"
#include "nb.h"
#include "director.h"
#include "mesh.h"
#include "meshvalue.h"
#include "simstate.h"
#include "threevector.h"
#include "rectangularmesh.h"
#include "energy.h"             // Needed to make MSVC++ 5 happy

#include "yy_stagemel.h"

OC_USE_STRING;

// Oxs_Ext registration support
OXS_EXT_REGISTER(YY_StageMEL);

/* End includes */

// Constructor
YY_StageMEL::YY_StageMEL(
  const char* name,     // Child instance id
  Oxs_Director* newdtr, // App director
  const char* argstr)   // MIF input block parameters
  : Oxs_Energy(name,newdtr,argstr), number_of_stages(0),
  mesh_id(0), stage_valid(0)
{
  YY_DEBUGMSG("YY_StageMEL constructor start.\n");
  working_stage = static_cast<OC_UINT4m>(static_cast<OC_INT4m>(-1));
  // First ChangeFileInitializer() call should be triggered
  // by the stage_valid boolean.

  // Process arguments
  hmult = GetRealInitValue("multiplier", 1.0);

  // Script name
  cmd.SetBaseCommand(InstanceName(),
                     director->GetMifInterp(),
                     GetStringInitValue("script"),1);
  number_of_stages = GetUIntInitValue("stage_count",0);

  // Generate MELCoef initializer
  if(HasInitValue("B1")) {
    OXS_GET_INIT_EXT_OBJECT("B1",Oxs_ScalarField,MELCoef1_init);
  } else {
    MELCoef1_init.SetAsOwner(dynamic_cast<Oxs_ScalarField *>
        (MakeNew("Oxs_UniformScalarField",director,"value 7.85e6")));
  }
  if(HasInitValue("B2")) {
    OXS_GET_INIT_EXT_OBJECT("B2",Oxs_ScalarField,MELCoef2_init);
  } else {
    MELCoef2_init.SetAsOwner(dynamic_cast<Oxs_ScalarField *>
        (MakeNew("Oxs_UniformScalarField",director,"value 7.85e6")));
  }

  // Initialize outputs.
  YY_DEBUGMSG("YY_StageMEL constructor initialize outputs.\n");
  B_MEL_output.Setup(this, InstanceName(), "B max", "mT", 1,
    &YY_StageMEL::Fill__B_MEL_output);
  B_MELx_output.Setup(this, InstanceName(), "Bx max", "mT", 1,
    &YY_StageMEL::Fill__B_MEL_output);
  B_MELy_output.Setup(this, InstanceName(), "By max", "mT", 1,
    &YY_StageMEL::Fill__B_MEL_output);
  B_MELz_output.Setup(this, InstanceName(), "Bz max", "mT", 1,
    &YY_StageMEL::Fill__B_MEL_output);

  // Register outputs.
  B_MEL_output.Register(director, 0);
  B_MELx_output.Register(director, 0);
  B_MELy_output.Register(director, 0);
  B_MELz_output.Register(director, 0);

  VerifyAllInitArgsUsed();
}

YY_StageMEL::~YY_StageMEL()
{}

OC_BOOL YY_StageMEL::Init()
{
  YY_DEBUGMSG("YY_StageMEL::Init(): start.\n");
  stage_valid = 0;

  mesh_id = 0;
  MELField.Release();

  YY_DEBUGMSG("YY_StageMEL::Init(): Calling Oxs_Energy::Init()\n");
  return Oxs_Energy::Init();
}

void YY_StageMEL::StageRequestCount(unsigned int& min,
    unsigned int& max) const
{
  if(number_of_stages == 0) {
    min = 0; max = UINT_MAX;  // No restriction on stage count
  } else {
    min = max = number_of_stages;
  }
}

void YY_StageMEL::ChangeDisplacementInitializer(
    OC_UINT4m stage, const Oxs_Mesh* mesh) const
{
  YY_DEBUGMSG("YY_StageMEL::ChangeDisplacementInitializer(): start.\n");
  // Setup displacement
  vector<String> params;
  if(filelist.empty()) {
    // Use cmd to generate field initializer
    YY_DEBUGMSG("YY_StageMEL::ChangeDisplacementInitializer(): filelist.empty.\n");
    cmd.SaveInterpResult();
    cmd.SetCommandArg(0,stage);
    cmd.Eval();
    cmd.GetResultList(params);
    cmd.RestoreInterpResult();
  } else {
    YY_DEBUGMSG("YY_StageMEL::ChangeDisplacementInitializer(): !filelist.empty.\n");
    // Construct field initializer using Oxs_FileVectorField
    // with filename from filelist and range from mesh.
    OC_UINT4m index = stage;
    OC_UINT4m filecount = static_cast<OC_UINT4m>(filelist.size());
    if(index >= filecount) index = filecount - 1;
    vector<String> options;
    options.push_back(String("file"));
    options.push_back(filelist[index]);

    Oxs_Box bbox;    mesh->GetBoundingBox(bbox);
    char buf[64];
    options.push_back(String("xrange"));
    Oc_Snprintf(buf,sizeof(buf),"%.17g %.17g",
                static_cast<double>(bbox.GetMinX()),
                static_cast<double>(bbox.GetMaxX()));
    options.push_back(String(buf));

    options.push_back(String("yrange"));
    Oc_Snprintf(buf,sizeof(buf),"%.17g %.17g",
                static_cast<double>(bbox.GetMinY()),
                static_cast<double>(bbox.GetMaxY()));
    options.push_back(String(buf));

    options.push_back(String("zrange"));
    Oc_Snprintf(buf,sizeof(buf),"%.17g %.17g",
                static_cast<double>(bbox.GetMinZ()),
                static_cast<double>(bbox.GetMaxZ()));
    options.push_back(String(buf));

    params.push_back(String("Oxs_FileVectorField"));
    params.push_back(Nb_MergeList(options));
  }

  //YY_DEBUGMSG("YY_StageMEL::ChangeDisplacementInitializer(): OXS_GET_EXT_OBJECT, displacement_init.\n");
  OXS_GET_EXT_OBJECT(params,Oxs_VectorField,displacement_init);
  working_stage = stage;
  stage_valid = 1;
}

void
YY_StageMEL::FillDisplacementCache(const Oxs_SimState& state) const
{
  const Oxs_Mesh* mesh = state.mesh;
  // Displacement
  YY_DEBUGMSG("YY_StageMEL::FillDisplacementCache(): FillMeshValue.\n");
  MELField.SetDisplacement(state, displacement_init);

}

void YY_StageMEL::UpdateCache(const Oxs_SimState& state) const
{
  // Update cache as necessary
  if(!stage_valid) {
    // The first go.
    YY_DEBUGMSG("YY_StageMEL:UpdateCache(): !stage_valide.\n");
    mesh_id = 0;
    MELField.SetMELCoef(state,MELCoef1_init,MELCoef2_init);
    ChangeDisplacementInitializer(state.stage_number,state.mesh);
    FillDisplacementCache(state);
  } else if(working_stage != state.stage_number) {
    mesh_id = 0;
    YY_DEBUGMSG("YY_StageMEL:UpdateCache(): ChangeDisplacementInitializer().\n");
    ChangeDisplacementInitializer(state.stage_number,state.mesh);
    YY_DEBUGMSG("YY_StageMEL:UpdateCache(): FillDisplacementCache().\n");
    FillDisplacementCache(state);
    mesh_id = state.mesh->Id();
  } else if(mesh_id != state.mesh->Id()) {
    mesh_id = 0;
    YY_DEBUGMSG("YY_StageMEL:UpdateCache(): in else, FillDisplacementCache().\n");
    FillDisplacementCache(state);
    mesh_id = state.mesh->Id();
  }
}

void YY_StageMEL::GetEnergy
(const Oxs_SimState& state, Oxs_EnergyData& oed) const
{
  YY_DEBUGMSG("YY_StageMEL::GetEnergy(): Beginning the method.\n");
  OC_INDEX size = state.mesh->Size();
  if(size<1) return;

  YY_DEBUGMSG("YY_StageMEL::GetEnergy(): UpdateCache().\n");
  UpdateCache(state);

  const Oxs_MeshValue<ThreeVector>& spin = state.spin;
  const Oxs_MeshValue<OC_REAL8m>& Ms = *(state.Ms);

  YY_DEBUGMSG("YY_StageMEL::GetEnergy(): Starting H_MEL calculation.\n");

  // Use supplied buffer space, and reflect that use in oed.
  oed.energy = oed.energy_buffer;
  oed.field = oed.field_buffer;
  Oxs_MeshValue<OC_REAL8m>& energy = *oed.energy_buffer;
  Oxs_MeshValue<ThreeVector>& field = *oed.field_buffer;
  energy.AdjustSize(state.mesh);
  field.AdjustSize(state.mesh);

  MELField.CalculateMELField(state, hmult, field);
  max_field = MELField.GetMaxField();

  // Calculate pointwise energy density -0.5*MU0*<M,Hmel>
  for(OC_INDEX i=0; i<size; i++) {
    energy[i] = -0.5 * MU0 * Ms[i] * (spin[i]*field[i]);
  }

}

void
YY_StageMEL::Fill__B_MEL_output(const Oxs_SimState& state)
{
  UpdateCache(state);

  ThreeVector B = max_field;
  B *= MU0 * 1000;  // Report B_MEL in mT

  if(B_MEL_output.GetCacheRequestCount() > 0) {
    B_MEL_output.cache.state_id = 0;
    B_MEL_output.cache.value = sqrt(B.MagSq());
    B_MEL_output.cache.state_id = state.Id();
  }

  if(B_MELx_output.GetCacheRequestCount() > 0) {
    B_MELx_output.cache.state_id = 0;
    B_MELx_output.cache.value = B.x;
    B_MELx_output.cache.state_id = state.Id();
  }

  if(B_MELy_output.GetCacheRequestCount() > 0) {
    B_MELy_output.cache.state_id = 0;
    B_MELy_output.cache.value = B.y;
    B_MELy_output.cache.state_id = state.Id();
  }

  if(B_MELz_output.GetCacheRequestCount() > 0) {
    B_MELz_output.cache.state_id = 0;
    B_MELz_output.cache.value = B.z;
    B_MELz_output.cache.state_id = state.Id();
  }
}

<commit_msg>[change] Removed default values for B1 and B2. Now it throws an errow when they are not specified in the mif file.<commit_after>/* FILE: yy_stagemel.cc                 -*-Mode: c++-*-
 *
 * OOMMF magnetoelastic coupling extension module.
 * YY_StageMEL class.
 * Calculates MEL field/energy for each stage.
 *
 */

#include "oc.h"
#include "nb.h"
#include "director.h"
#include "mesh.h"
#include "meshvalue.h"
#include "simstate.h"
#include "threevector.h"
#include "rectangularmesh.h"
#include "energy.h"             // Needed to make MSVC++ 5 happy

#include "yy_stagemel.h"

OC_USE_STRING;

// Oxs_Ext registration support
OXS_EXT_REGISTER(YY_StageMEL);

/* End includes */

// Constructor
YY_StageMEL::YY_StageMEL(
  const char* name,     // Child instance id
  Oxs_Director* newdtr, // App director
  const char* argstr)   // MIF input block parameters
  : Oxs_Energy(name,newdtr,argstr), number_of_stages(0),
  mesh_id(0), stage_valid(0)
{
  YY_DEBUGMSG("YY_StageMEL constructor start.\n");
  working_stage = static_cast<OC_UINT4m>(static_cast<OC_INT4m>(-1));
  // First ChangeFileInitializer() call should be triggered
  // by the stage_valid boolean.

  // Process arguments
  hmult = GetRealInitValue("multiplier", 1.0);

  // Script name
  cmd.SetBaseCommand(InstanceName(),
                     director->GetMifInterp(),
                     GetStringInitValue("script"),1);
  number_of_stages = GetUIntInitValue("stage_count",0);

  // Generate MELCoef initializer
  OXS_GET_INIT_EXT_OBJECT("B1",Oxs_ScalarField,MELCoef1_init);
  OXS_GET_INIT_EXT_OBJECT("B2",Oxs_ScalarField,MELCoef2_init);

  // Initialize outputs.
  YY_DEBUGMSG("YY_StageMEL constructor initialize outputs.\n");
  B_MEL_output.Setup(this, InstanceName(), "B max", "mT", 1,
    &YY_StageMEL::Fill__B_MEL_output);
  B_MELx_output.Setup(this, InstanceName(), "Bx max", "mT", 1,
    &YY_StageMEL::Fill__B_MEL_output);
  B_MELy_output.Setup(this, InstanceName(), "By max", "mT", 1,
    &YY_StageMEL::Fill__B_MEL_output);
  B_MELz_output.Setup(this, InstanceName(), "Bz max", "mT", 1,
    &YY_StageMEL::Fill__B_MEL_output);

  // Register outputs.
  B_MEL_output.Register(director, 0);
  B_MELx_output.Register(director, 0);
  B_MELy_output.Register(director, 0);
  B_MELz_output.Register(director, 0);

  VerifyAllInitArgsUsed();
}

YY_StageMEL::~YY_StageMEL()
{}

OC_BOOL YY_StageMEL::Init()
{
  YY_DEBUGMSG("YY_StageMEL::Init(): start.\n");
  stage_valid = 0;

  mesh_id = 0;
  MELField.Release();

  YY_DEBUGMSG("YY_StageMEL::Init(): Calling Oxs_Energy::Init()\n");
  return Oxs_Energy::Init();
}

void YY_StageMEL::StageRequestCount(unsigned int& min,
    unsigned int& max) const
{
  if(number_of_stages == 0) {
    min = 0; max = UINT_MAX;  // No restriction on stage count
  } else {
    min = max = number_of_stages;
  }
}

void YY_StageMEL::ChangeDisplacementInitializer(
    OC_UINT4m stage, const Oxs_Mesh* mesh) const
{
  YY_DEBUGMSG("YY_StageMEL::ChangeDisplacementInitializer(): start.\n");
  // Setup displacement
  vector<String> params;
  if(filelist.empty()) {
    // Use cmd to generate field initializer
    YY_DEBUGMSG("YY_StageMEL::ChangeDisplacementInitializer(): filelist.empty.\n");
    cmd.SaveInterpResult();
    cmd.SetCommandArg(0,stage);
    cmd.Eval();
    cmd.GetResultList(params);
    cmd.RestoreInterpResult();
  } else {
    YY_DEBUGMSG("YY_StageMEL::ChangeDisplacementInitializer(): !filelist.empty.\n");
    // Construct field initializer using Oxs_FileVectorField
    // with filename from filelist and range from mesh.
    OC_UINT4m index = stage;
    OC_UINT4m filecount = static_cast<OC_UINT4m>(filelist.size());
    if(index >= filecount) index = filecount - 1;
    vector<String> options;
    options.push_back(String("file"));
    options.push_back(filelist[index]);

    Oxs_Box bbox;    mesh->GetBoundingBox(bbox);
    char buf[64];
    options.push_back(String("xrange"));
    Oc_Snprintf(buf,sizeof(buf),"%.17g %.17g",
                static_cast<double>(bbox.GetMinX()),
                static_cast<double>(bbox.GetMaxX()));
    options.push_back(String(buf));

    options.push_back(String("yrange"));
    Oc_Snprintf(buf,sizeof(buf),"%.17g %.17g",
                static_cast<double>(bbox.GetMinY()),
                static_cast<double>(bbox.GetMaxY()));
    options.push_back(String(buf));

    options.push_back(String("zrange"));
    Oc_Snprintf(buf,sizeof(buf),"%.17g %.17g",
                static_cast<double>(bbox.GetMinZ()),
                static_cast<double>(bbox.GetMaxZ()));
    options.push_back(String(buf));

    params.push_back(String("Oxs_FileVectorField"));
    params.push_back(Nb_MergeList(options));
  }

  //YY_DEBUGMSG("YY_StageMEL::ChangeDisplacementInitializer(): OXS_GET_EXT_OBJECT, displacement_init.\n");
  OXS_GET_EXT_OBJECT(params,Oxs_VectorField,displacement_init);
  working_stage = stage;
  stage_valid = 1;
}

void
YY_StageMEL::FillDisplacementCache(const Oxs_SimState& state) const
{
  const Oxs_Mesh* mesh = state.mesh;
  // Displacement
  YY_DEBUGMSG("YY_StageMEL::FillDisplacementCache(): FillMeshValue.\n");
  MELField.SetDisplacement(state, displacement_init);

}

void YY_StageMEL::UpdateCache(const Oxs_SimState& state) const
{
  // Update cache as necessary
  if(!stage_valid) {
    // The first go.
    YY_DEBUGMSG("YY_StageMEL:UpdateCache(): !stage_valide.\n");
    mesh_id = 0;
    MELField.SetMELCoef(state,MELCoef1_init,MELCoef2_init);
    ChangeDisplacementInitializer(state.stage_number,state.mesh);
    FillDisplacementCache(state);
  } else if(working_stage != state.stage_number) {
    mesh_id = 0;
    YY_DEBUGMSG("YY_StageMEL:UpdateCache(): ChangeDisplacementInitializer().\n");
    ChangeDisplacementInitializer(state.stage_number,state.mesh);
    YY_DEBUGMSG("YY_StageMEL:UpdateCache(): FillDisplacementCache().\n");
    FillDisplacementCache(state);
    mesh_id = state.mesh->Id();
  } else if(mesh_id != state.mesh->Id()) {
    mesh_id = 0;
    YY_DEBUGMSG("YY_StageMEL:UpdateCache(): in else, FillDisplacementCache().\n");
    FillDisplacementCache(state);
    mesh_id = state.mesh->Id();
  }
}

void YY_StageMEL::GetEnergy
(const Oxs_SimState& state, Oxs_EnergyData& oed) const
{
  YY_DEBUGMSG("YY_StageMEL::GetEnergy(): Beginning the method.\n");
  OC_INDEX size = state.mesh->Size();
  if(size<1) return;

  YY_DEBUGMSG("YY_StageMEL::GetEnergy(): UpdateCache().\n");
  UpdateCache(state);

  const Oxs_MeshValue<ThreeVector>& spin = state.spin;
  const Oxs_MeshValue<OC_REAL8m>& Ms = *(state.Ms);

  YY_DEBUGMSG("YY_StageMEL::GetEnergy(): Starting H_MEL calculation.\n");

  // Use supplied buffer space, and reflect that use in oed.
  oed.energy = oed.energy_buffer;
  oed.field = oed.field_buffer;
  Oxs_MeshValue<OC_REAL8m>& energy = *oed.energy_buffer;
  Oxs_MeshValue<ThreeVector>& field = *oed.field_buffer;
  energy.AdjustSize(state.mesh);
  field.AdjustSize(state.mesh);

  MELField.CalculateMELField(state, hmult, field);
  max_field = MELField.GetMaxField();

  // Calculate pointwise energy density -0.5*MU0*<M,Hmel>
  for(OC_INDEX i=0; i<size; i++) {
    energy[i] = -0.5 * MU0 * Ms[i] * (spin[i]*field[i]);
  }

}

void
YY_StageMEL::Fill__B_MEL_output(const Oxs_SimState& state)
{
  UpdateCache(state);

  ThreeVector B = max_field;
  B *= MU0 * 1000;  // Report B_MEL in mT

  if(B_MEL_output.GetCacheRequestCount() > 0) {
    B_MEL_output.cache.state_id = 0;
    B_MEL_output.cache.value = sqrt(B.MagSq());
    B_MEL_output.cache.state_id = state.Id();
  }

  if(B_MELx_output.GetCacheRequestCount() > 0) {
    B_MELx_output.cache.state_id = 0;
    B_MELx_output.cache.value = B.x;
    B_MELx_output.cache.state_id = state.Id();
  }

  if(B_MELy_output.GetCacheRequestCount() > 0) {
    B_MELy_output.cache.state_id = 0;
    B_MELy_output.cache.value = B.y;
    B_MELy_output.cache.state_id = state.Id();
  }

  if(B_MELz_output.GetCacheRequestCount() > 0) {
    B_MELz_output.cache.state_id = 0;
    B_MELz_output.cache.value = B.z;
    B_MELz_output.cache.state_id = state.Id();
  }
}

<|endoftext|>