<commit_before>/******************************************************************************
* Controller_Functions.cpp
*
* Contains the marchPID() and depth_controller functions
******************************************************************************/
#include "Mapper.h"

/******************************************************************************
* float marchPID()
*
* Takes in readings from the IMU and returns a value between -1 and 1 (-100% -
* +100%) that the port and starboard thrusters should run at
******************************************************************************/

float marchPID(pid_data_t controller, float input)
{
	// Calculating errors
	controller.perr = input - controller.setpoint;
	controller.derr = (input - controller.old)/(controller.dt);
	controller.ierr += controller.dt * (input - controller.setpoint);

	if(controller.ierr > controller.isat)
	{
		controller.ierr = controller.isat;
	}

	if(controller.ierr < -controller.isat)
	{
		controller.ierr = - controller.isat;
	}

	controller.output =   controller.kp * controller.perr
						+ controller.ki * controller.ierr
						+ controller.kd * controller.derr;

	if(controller.output > controller.sat)
	{
		controller.output = controller.sat;
	}

	if(controller.output < -controller.sat)
	{
		controller.output = -controller.sat;
	}
	// set current input to be the old input //
	controller.old = input;

	return controller.output;
}

/******************************************************************************
 * int initialize_motors(int channels[3], float freq)
 *
 * Initializes the PWM board and the ESCs that run the motors
******************************************************************************/
int initialize_motors(int channels[3], float freq)
{
	// integer specifying motor number //
	int i;

	// setup PCA9685 PWM board //
	int fd = pca9685Setup(PIN_BASE, PCA9685_ADDR, HERTZ);
	if (fd < 0)
	{
		printf("Error in setup\n");
		return fd;
	}

	// reset all PCA9685 PWM board output //
	pca9685PWMReset(fd);

	// set motor outputs to 0 to initialize ESCs //
	int active=1;
		while (active)
		{
			for( i = 0; i < 3; i++ )
			{
				// send "neutral" signal to arm ESCs //
				pwmWrite (PIN_BASE+i, MOTOR_0);
				active=0;
			}
		}
	return fd;
}

/******************************************************************************
 * int set_motor(int motornum, float percent)
 *
 * Takes in a value from -1 to 1 (-100 to +100%) and sets the motor
 * outputs accordingly
******************************************************************************/
int set_motor(int motornum, float percent)
{
  // Define characteristics of PWM pulse, microseconds
	float amplitude  = PWM_HIGH_LIMIT - PWM_ZERO_VALUE;

	// Saturation limits
  if( percent >  1.0) percent =  1.0;
  if( percent < -1.0) percent = -1.0;

  // Deadzone check
  if( (percent < MOTOR_DEADZONE) && (percent > -MOTOR_DEADZONE) ) percent = 0.0;

	// Calculate corresponding pwm output value
	int motoroutput = percent * amplitude + PWM_ZERO_VALUE;

	// Spin those motors
  pwmWrite(motornum + PIN_BASE, motoroutput);

  #ifdef DEBUG
  // Print what we told the motor to spin at.
  printf("Set motor %d to %d \n",motornum, motoroutput);
  #endif

	return 1;
}

/***************************************************************************
 * int saturate_number(float* val, float min, float max)
 *
 * Generic function for saturating values in a function
***************************************************************************/
int saturate_number(float* val, float min, float max)
{
	// if "val" is greater than "max", set "val" to "max" //
	if(*val>max)
	{
		*val = max;
		return 1;
	}

	// if "val" is less than "min", set "val" to "min" //
	else if(*val<min)
	{
		*val = min;
		return 1;
	}
	return 0;
}
<commit_msg>controller-->PID<commit_after>/******************************************************************************
* Controller_Functions.cpp
*
* Contains the marchPID() and depth_controller functions
******************************************************************************/
#include "Mapper.h"

/******************************************************************************
* float marchPID()
*
* Takes in readings from the IMU and returns a value between -1 and 1 (-100% -
* +100%) that the port and starboard thrusters should run at
******************************************************************************/

float marchPID(pid_data_t PID, float input)
{
	// Calculating errors
	PID.perr = input - PID.setpoint;
	PID.derr = (input - PID.old)/(PID.dt);
	PID.ierr += PID.dt * (input - PID.setpoint);

	if(PID.ierr > PID.isat)
	{
		PID.ierr = PID.isat;
	}

	if(PID.ierr < -PID.isat)
	{
		PID.ierr = - PID.isat;
	}

	PID.output =   PID.kp * PID.perr
						+ PID.ki * PID.ierr
						+ PID.kd * PID.derr;

	if(PID.output > PID.sat)
	{
		PID.output = PID.sat;
	}

	if(PID.output < -PID.sat)
	{
		PID.output = -PID.sat;
	}
	// set current input to be the old input //
	PID.old = input;

	return PID.output;
}

/******************************************************************************
 * int initialize_motors(int channels[3], float freq)
 *
 * Initializes the PWM board and the ESCs that run the motors
******************************************************************************/
int initialize_motors(int channels[3], float freq)
{
	// integer specifying motor number //
	int i;

	// setup PCA9685 PWM board //
	int fd = pca9685Setup(PIN_BASE, PCA9685_ADDR, HERTZ);
	if (fd < 0)
	{
		printf("Error in setup\n");
		return fd;
	}

	// reset all PCA9685 PWM board output //
	pca9685PWMReset(fd);

	// set motor outputs to 0 to initialize ESCs //
	int active=1;
		while (active)
		{
			for( i = 0; i < 3; i++ )
			{
				// send "neutral" signal to arm ESCs //
				pwmWrite (PIN_BASE+i, MOTOR_0);
				active=0;
			}
		}
	return fd;
}

/******************************************************************************
 * int set_motor(int motornum, float percent)
 *
 * Takes in a value from -1 to 1 (-100 to +100%) and sets the motor
 * outputs accordingly
******************************************************************************/
int set_motor(int motornum, float percent)
{
  // Define characteristics of PWM pulse, microseconds
	float amplitude  = PWM_HIGH_LIMIT - PWM_ZERO_VALUE;

	// Saturation limits
  if( percent >  1.0) percent =  1.0;
  if( percent < -1.0) percent = -1.0;

  // Deadzone check
  if( (percent < MOTOR_DEADZONE) && (percent > -MOTOR_DEADZONE) ) percent = 0.0;

	// Calculate corresponding pwm output value
	int motoroutput = percent * amplitude + PWM_ZERO_VALUE;

	// Spin those motors
  pwmWrite(motornum + PIN_BASE, motoroutput);

  #ifdef DEBUG
  // Print what we told the motor to spin at.
  printf("Set motor %d to %d \n",motornum, motoroutput);
  #endif

	return 1;
}

/***************************************************************************
 * int saturate_number(float* val, float min, float max)
 *
 * Generic function for saturating values in a function
***************************************************************************/
int saturate_number(float* val, float min, float max)
{
	// if "val" is greater than "max", set "val" to "max" //
	if(*val>max)
	{
		*val = max;
		return 1;
	}

	// if "val" is less than "min", set "val" to "min" //
	else if(*val<min)
	{
		*val = min;
		return 1;
	}
	return 0;
}
<|endoftext|>


<commit_before>#include "StableHeaders.h"
#include "Connection.h"
#include "MumbleVoipModule.h"

//#include "celt.h"
#define BUILDING_DLL // for dll import/export declarations
#define CreateEvent CreateEventW // for \boost\asio\detail\win_event.hpp and \boost\asio\detail\win_iocp_handle_service.hpp
#include <mumbleclient/client.h>
#include <mumbleclient/client_lib.h>
#include <mumbleclient/channel.h>
#undef BUILDING_DLL // for dll import/export declarations
#include <mumbleclient/settings.h>
//#include <boost/make_shared.hpp>

#include "SoundServiceInterface.h"
#include "Channel.h"
#include "PCMAudioFrame.h"
#include <mumbleclient/PacketDataStream.h>
#include <libcelt/celt.h>

namespace MumbleVoip {

//struct RelayMessage {
//	MumbleClient::MumbleClient* mc;
//	const std::string message;
//	RelayMessage(MumbleClient::MumbleClient* mc_, const std::string& message_) : mc(mc_), message(message_) { }
//};

//static boost::mutex mut;
//static std::deque< boost::shared_ptr<RelayMessage> > relay_queue;
//static boost::condition_variable cond;

//
//

    // \todo Move these static callback functions to separeate file...

static inline int32_t pds_int_len(char* x)
{
	if ((x[0] & 0x80) == 0x00) {
		return 1;
	} else if ((x[0] & 0xC0) == 0x80) {
		return 2;
	} else if ((x[0] & 0xF0) == 0xF0) {
		switch (x[0] & 0xFC) {
			case 0xF0:
				return 5;
			case 0xF4:
				return 9;
			case 0xF8:
				return pds_int_len(&x[1]) + 1;
			case 0xFC:
				return 1;
			default:
				return 1;
		}
	} else if ((x[0] & 0xF0) == 0xE0) {
		return 3;
	} else if ((x[0] & 0xE0) == 0xC0) {
		return 3;
	}

	return 0;
}

int scanPacket(char* data, int len) {
	int header = 0;
	int frames = 0;
	// skip flags
	int pos = 1;

	// skip session & seqnr
	pos += pds_int_len(&data[pos]);
	pos += pds_int_len(&data[pos]);

	bool valid = true;
	do {
		header = static_cast<unsigned char>(data[pos]);
		++pos;
		++frames;
		pos += (header & 0x7f);

		if (pos > len)
			valid = false;
	} while ((header & 0x80) && valid);

	if (valid) {
		return frames;
	} else {
		return -1;
	}
}

void TextMessageCallback(const std::string& message, Connection* connection)
{
    connection->OnTextMessageCallback(QString(message.c_str()));
}

//void RelayTunnelCallback(int32_t length, void* buffer, MumbleClient::MumbleClient* mc)
//{
//	std::string s(static_cast<char *>(buffer), length);
//	s.erase(1, pds_int_len(&static_cast<char *>(buffer)[1]));
//	boost::shared_ptr<RelayMessage> r = boost::make_shared<RelayMessage>(mc, s);
//	{
//		boost::lock_guard<boost::mutex> lock(mut);
//		relay_queue.push_back(r);
//	}
//	cond.notify_all();
//}

void RawUdpTunnelCallback(int32_t length, void* buffer, Connection* connection)
{
    connection->OnRawUdpTunnelCallback(length, buffer);
}

void RelayTunnelCallback(int32_t length, void* buffer_, Connection* connection)
{
 //   PacketDataStream data_stream = PacketDataStream((char*)buffer_, length);
 //   bool valid = data_stream.isValid();
 //   int size = data_stream.size();
 //   char* buffer = (char*)buffer_;
 //   short type = buffer[0] << 8 + buffer[1];
 //   int len = buffer[3] << 16 + buffer[4] << 8 + buffer[5];
	//std::string s(static_cast<char *>(buffer), length);
	//s.erase(1, pds_int_len(&static_cast<char *>(buffer)[1]));
//    connection->OnRelayTunnel(s);
}

void AuthCallback(Connection* connection)
{
    connection->OnAuthCallback();
}

void ChannelAddCallback(const MumbleClient::Channel& channel, Connection* connection)
{
    connection->OnChannelAddCallback(channel);
}

void ChannelRemoveCallback(const MumbleClient::Channel& channel, Connection* connection)
{
    connection->OnChannelRemoveCallback(channel);
}

Connection::Connection(ServerInfo &info) :
        client_(0),
        authenticated_(false),
        celt_mode_(0),
        celt_encoder_(0),
        celt_decoder_(0),
        sending_audio_(false),
        frame_sequence_(0)
{
    InitializeCELT();

    MumbleClient::MumbleClientLib* mumble_lib = MumbleClient::MumbleClientLib::instance();
    client_ = mumble_lib->NewClient();

    QString port = "64738"; // default port name
    // \todo Handle connection error
    client_->Connect(MumbleClient::Settings(info.server.toStdString(), port.toStdString(), info.user_name.toStdString(), info.password.toStdString()));
	client_->SetRawUdpTunnelCallback( boost::bind(&RawUdpTunnelCallback, _1, _2, this));
    client_->SetChannelAddCallback(boost::bind(&ChannelAddCallback, _1, this));
    client_->SetChannelRemoveCallback(boost::bind(&ChannelRemoveCallback, _1, this));
    client_->SetTextMessageCallback(boost::bind(&TextMessageCallback, _1, this));
    client_->SetAuthCallback(boost::bind(&AuthCallback, this));
}

Connection::~Connection()
{
    UninitializeCELT();
    SAFE_DELETE(client_);
    // \todo clean playback queue
    // \todo clean send queue
    // \todo clean channel list
}

void Connection::Close()
{
    client_->Disconnect();
}

void Connection::InitializeCELT()
{
    int error = 0;
    int channels = 1;
    int framesize = SAMPLE_RATE_ / 100;
    celt_mode_ = celt_mode_create(SAMPLE_RATE_, channels, framesize, &error );
    if (error != 0)
    {
        QString message = QString("CELT initialization failed, error code = %1").arg(error);
        MumbleVoipModule::LogDebug(message.toStdString());
    }
    celt_encoder_ = celt_encoder_create(celt_mode_);
    celt_decoder_ = celt_decoder_create(celt_mode_);
    MumbleVoipModule::LogDebug("CELT initialized.");
}

void Connection::UninitializeCELT()
{
    celt_decoder_destroy(celt_decoder_);
    celt_encoder_destroy(celt_encoder_);
    celt_mode_destroy(celt_mode_);
    MumbleVoipModule::LogDebug("CELT uninitialized.");
}

void Connection::Join(QString channel_name)
{
    QMutexLocker locker1(&mutex_authentication_);
    QMutexLocker locker2(&mutex_channels_);

    if (!authenticated_)
    {
        join_request_ = channel_name;
        return; // @todo: Throw exception
    }

    foreach(Channel* c, channels_)
    {
        if (c->Name() == channel_name)
        {
            client_->JoinChannel(c->Id());
        }
    }
}

void Connection::OnAuthCallback()
{
    mutex_authentication_.lock();
    authenticated_ = true;
    mutex_authentication_.unlock();

    if (join_request_.length() > 0)
    {
        QString channel = join_request_;
        join_request_ = "";
        Join(channel);
    }
}

void Connection::OnTextMessageCallback(QString text)
{
    emit (TextMessage(text));
}

PCMAudioFrame* Connection::GetAudioFrame()
{
    QMutexLocker locker(&mutex_playback_queue_);

    if (playback_queue_.size() == 0)
        return 0;

    PCMAudioFrame* frame = playback_queue_.takeFirst();
    return frame;
}

void Connection::SendAudioFrame(PCMAudioFrame* frame)
{
    int audio_quality = 60000;
    int frames_per_packet = 6;

    QMutexLocker locker(&mutex_encode_audio_);

    if (encode_queue_.size < 100)
        encode_queue_.push_back(frame);
    if (encode_queue_.size() < frames_per_packet)
        return;

    std::deque<std::string> packet_list;
    celt_encoder_ctl(celt_encoder_, CELT_SET_LTP(0));
	//celt_encoder_ctl(celt_encode, CELT_SET_VBR_RATE(audio_quality));

    for (int i = 0; i < frames_per_packet; ++i)
    {
        PCMAudioFrame* audio_frame = encode_queue_.first();
        encode_queue_.pop_front();

        int32_t len = celt_encode(celt_encoder_, reinterpret_cast<short *>(audio_frame->Data()), NULL, encode_buffer_, std::min(audio_quality / (100 * 8), 127));
        packet_list.push_back(std::string(reinterpret_cast<char *>(encode_buffer_), len));

        delete audio_frame;
    }
//    int32_t seq = 0;
    int session = 0;
	char data[1024];
	int flags = 0; // target = 0
	flags |= (MumbleClient::UdpMessageType::UDPVoiceCELTAlpha << 5);
	data[0] = static_cast<unsigned char>(flags);
    PacketDataStream data_stream(data + 1, 1023);
    data_stream << session;
    data_stream << frame_sequence_;

	for (int i = 0; i < frames_per_packet; ++i)
    {
		if (packet_list.empty())
            break;

		const std::string& s = packet_list.front();

		unsigned char head = s.size();
		// Add 0x80 to all but the last frame
		if (i < frames_per_packet - 1)
			head |= 0x80;

		data_stream.append(head);
		data_stream.append(s);

		packet_list.pop_front();
	}
    client_->SendRawUdpTunnel(data, data_stream.size() + 1 );
    frame_sequence_ += frames_per_packet;
}

void Connection::OnChannelAddCallback(const MumbleClient::Channel& channel)
{
    QMutexLocker locker(&mutex_channels_);

    Channel* c = new Channel(channel);
    channels_.append(c);
    QString message = QString("Channel '%1' added").arg(c->Name());
    MumbleVoipModule::LogDebug(message.toStdString());
}

void Connection::OnChannelRemoveCallback(const MumbleClient::Channel& channel)
{
    QMutexLocker locker(&mutex_channels_);

    int i = 0;
    for (int i = 0; i < channels_.size(); ++i)
    {
        if (channels_.at(i)->Id() == channel.id)
        {
            channels_.removeAt(i);
            return;
        }
    }
}

void Connection::OnRawUdpTunnelCallback(int32_t length, void* buffer)
{
    return; // test

    int frames = scanPacket((char*)buffer, length);

    PacketDataStream data_stream = PacketDataStream((char*)buffer, length);
    bool valid = data_stream.isValid();

    uint8_t first_byte = data_stream.next();
    MumbleClient::UdpMessageType::MessageType type = static_cast<MumbleClient::UdpMessageType::MessageType>( ( first_byte >> 5) & 0x07 );
    uint8_t flags = first_byte & 0x1f;
    switch (type)
    {
    case MumbleClient::UdpMessageType::UDPVoiceCELTAlpha:
        break;
    case MumbleClient::UdpMessageType::UDPPing:
        MumbleVoipModule::LogDebug("MUMBLE-UDP: PING");
        return;
        break;
    case MumbleClient::UdpMessageType::UDPVoiceSpeex:
        MumbleVoipModule::LogDebug("MUMBLE-UDP: Speex");
        return;
        break;
    case MumbleClient::UdpMessageType::UDPVoiceCELTBeta:
        MumbleVoipModule::LogDebug("MUMBLE-UDP: CELT B");
        return;
        break;
    }

    //int skip = pds_int_len(data_stream.charPtr());
    //data_stream.skip(skip);

    //skip = pds_int_len(data_stream.charPtr());
    //data_stream.skip(skip);

    int session;
    int seq;
    data_stream >> session;
    data_stream >> seq;

    bool last_frame = true;
    do
    {
		int header = static_cast<unsigned char>(data_stream.next());
        int frame_size = header & 0x7f;
        last_frame = !(header & 0x80);
        const char* frame_data = data_stream.charPtr();
        data_stream.skip(frame_size);

        HandleIncomingCELTFrame((unsigned char*)frame_data, frame_size);
	} while (!last_frame && data_stream.isValid());

    int bytes_left = data_stream.left();
    if (bytes_left)
    {
        float position[3];
        data_stream >> position[0];
        data_stream >> position[1];
        data_stream >> position[2];
    }
}

QList<QString> Connection::Channels()
{
    QMutexLocker locker(&mutex_channels_);

    QList<QString> channels;
    foreach(Channel* c, channels_)
    {
        channels.append(c->Name());
    }
    return channels;
}

void Connection::SendAudio(bool send)
{
    sending_audio_ = send;
}

bool Connection::SendingAudio()
{
    return sending_audio_;
}

void Connection::HandleIncomingCELTFrame(unsigned char* data, int size)
{
    QMutexLocker locker(&mutex_playback_queue_);

    //celt_mode_info(celt_mode_, ???, sample_rate);
    int sample_count = 480;
    celt_int16_t pcm_data[480];
    int ret = celt_decode(celt_decoder_, data, size, pcm_data);
    switch (ret)
    {
    case CELT_OK:
        {
            if (playback_queue_.size() < 100)
            {
                PCMAudioFrame* audio_frame = new PCMAudioFrame(48000, 16, 1, (char*)pcm_data, 2*480);
                playback_queue_.push_back(audio_frame);
                emit AudioFramesAvailable(this);
            }
            else
            {
                MumbleVoipModule::LogWarning("Drop Mumble audio packet");
                return;
            }
        }
        break;
    case CELT_BAD_ARG:
        break;
    case CELT_INVALID_MODE:
        break;
    case CELT_INTERNAL_ERROR:
        break;
    case CELT_CORRUPTED_DATA:
        break;
    case CELT_UNIMPLEMENTED:
        break;
    }
}

} // namespace MumbleVoip
<commit_msg>Enable playback<commit_after>#include "StableHeaders.h"
#include "Connection.h"
#include "MumbleVoipModule.h"

//#include "celt.h"
#define BUILDING_DLL // for dll import/export declarations
#define CreateEvent CreateEventW // for \boost\asio\detail\win_event.hpp and \boost\asio\detail\win_iocp_handle_service.hpp
#include <mumbleclient/client.h>
#include <mumbleclient/client_lib.h>
#include <mumbleclient/channel.h>
#undef BUILDING_DLL // for dll import/export declarations
#include <mumbleclient/settings.h>
//#include <boost/make_shared.hpp>

#include "SoundServiceInterface.h"
#include "Channel.h"
#include "PCMAudioFrame.h"
#include <mumbleclient/PacketDataStream.h>
#include <libcelt/celt.h>

namespace MumbleVoip {

//struct RelayMessage {
//	MumbleClient::MumbleClient* mc;
//	const std::string message;
//	RelayMessage(MumbleClient::MumbleClient* mc_, const std::string& message_) : mc(mc_), message(message_) { }
//};

//static boost::mutex mut;
//static std::deque< boost::shared_ptr<RelayMessage> > relay_queue;
//static boost::condition_variable cond;

//
//

    // \todo Move these static callback functions to separeate file...

static inline int32_t pds_int_len(char* x)
{
	if ((x[0] & 0x80) == 0x00) {
		return 1;
	} else if ((x[0] & 0xC0) == 0x80) {
		return 2;
	} else if ((x[0] & 0xF0) == 0xF0) {
		switch (x[0] & 0xFC) {
			case 0xF0:
				return 5;
			case 0xF4:
				return 9;
			case 0xF8:
				return pds_int_len(&x[1]) + 1;
			case 0xFC:
				return 1;
			default:
				return 1;
		}
	} else if ((x[0] & 0xF0) == 0xE0) {
		return 3;
	} else if ((x[0] & 0xE0) == 0xC0) {
		return 3;
	}

	return 0;
}

int scanPacket(char* data, int len) {
	int header = 0;
	int frames = 0;
	// skip flags
	int pos = 1;

	// skip session & seqnr
	pos += pds_int_len(&data[pos]);
	pos += pds_int_len(&data[pos]);

	bool valid = true;
	do {
		header = static_cast<unsigned char>(data[pos]);
		++pos;
		++frames;
		pos += (header & 0x7f);

		if (pos > len)
			valid = false;
	} while ((header & 0x80) && valid);

	if (valid) {
		return frames;
	} else {
		return -1;
	}
}

void TextMessageCallback(const std::string& message, Connection* connection)
{
    connection->OnTextMessageCallback(QString(message.c_str()));
}

//void RelayTunnelCallback(int32_t length, void* buffer, MumbleClient::MumbleClient* mc)
//{
//	std::string s(static_cast<char *>(buffer), length);
//	s.erase(1, pds_int_len(&static_cast<char *>(buffer)[1]));
//	boost::shared_ptr<RelayMessage> r = boost::make_shared<RelayMessage>(mc, s);
//	{
//		boost::lock_guard<boost::mutex> lock(mut);
//		relay_queue.push_back(r);
//	}
//	cond.notify_all();
//}

void RawUdpTunnelCallback(int32_t length, void* buffer, Connection* connection)
{
    connection->OnRawUdpTunnelCallback(length, buffer);
}

void RelayTunnelCallback(int32_t length, void* buffer_, Connection* connection)
{
 //   PacketDataStream data_stream = PacketDataStream((char*)buffer_, length);
 //   bool valid = data_stream.isValid();
 //   int size = data_stream.size();
 //   char* buffer = (char*)buffer_;
 //   short type = buffer[0] << 8 + buffer[1];
 //   int len = buffer[3] << 16 + buffer[4] << 8 + buffer[5];
	//std::string s(static_cast<char *>(buffer), length);
	//s.erase(1, pds_int_len(&static_cast<char *>(buffer)[1]));
//    connection->OnRelayTunnel(s);
}

void AuthCallback(Connection* connection)
{
    connection->OnAuthCallback();
}

void ChannelAddCallback(const MumbleClient::Channel& channel, Connection* connection)
{
    connection->OnChannelAddCallback(channel);
}

void ChannelRemoveCallback(const MumbleClient::Channel& channel, Connection* connection)
{
    connection->OnChannelRemoveCallback(channel);
}

Connection::Connection(ServerInfo &info) :
        client_(0),
        authenticated_(false),
        celt_mode_(0),
        celt_encoder_(0),
        celt_decoder_(0),
        sending_audio_(false),
        frame_sequence_(0)
{
    InitializeCELT();

    MumbleClient::MumbleClientLib* mumble_lib = MumbleClient::MumbleClientLib::instance();
    client_ = mumble_lib->NewClient();

    QString port = "64738"; // default port name
    // \todo Handle connection error
    client_->Connect(MumbleClient::Settings(info.server.toStdString(), port.toStdString(), info.user_name.toStdString(), info.password.toStdString()));
	client_->SetRawUdpTunnelCallback( boost::bind(&RawUdpTunnelCallback, _1, _2, this));
    client_->SetChannelAddCallback(boost::bind(&ChannelAddCallback, _1, this));
    client_->SetChannelRemoveCallback(boost::bind(&ChannelRemoveCallback, _1, this));
    client_->SetTextMessageCallback(boost::bind(&TextMessageCallback, _1, this));
    client_->SetAuthCallback(boost::bind(&AuthCallback, this));
}

Connection::~Connection()
{
    UninitializeCELT();
    SAFE_DELETE(client_);
    // \todo clean playback queue
    // \todo clean send queue
    // \todo clean channel list
}

void Connection::Close()
{
    client_->Disconnect();
}

void Connection::InitializeCELT()
{
    int error = 0;
    int channels = 1;
    int framesize = SAMPLE_RATE_ / 100;
    celt_mode_ = celt_mode_create(SAMPLE_RATE_, channels, framesize, &error );
    if (error != 0)
    {
        QString message = QString("CELT initialization failed, error code = %1").arg(error);
        MumbleVoipModule::LogDebug(message.toStdString());
    }
    celt_encoder_ = celt_encoder_create(celt_mode_);
    celt_decoder_ = celt_decoder_create(celt_mode_);
    MumbleVoipModule::LogDebug("CELT initialized.");
}

void Connection::UninitializeCELT()
{
    celt_decoder_destroy(celt_decoder_);
    celt_encoder_destroy(celt_encoder_);
    celt_mode_destroy(celt_mode_);
    MumbleVoipModule::LogDebug("CELT uninitialized.");
}

void Connection::Join(QString channel_name)
{
    QMutexLocker locker1(&mutex_authentication_);
    QMutexLocker locker2(&mutex_channels_);

    if (!authenticated_)
    {
        join_request_ = channel_name;
        return; // @todo: Throw exception
    }

    foreach(Channel* c, channels_)
    {
        if (c->Name() == channel_name)
        {
            client_->JoinChannel(c->Id());
        }
    }
}

void Connection::OnAuthCallback()
{
    mutex_authentication_.lock();
    authenticated_ = true;
    mutex_authentication_.unlock();

    if (join_request_.length() > 0)
    {
        QString channel = join_request_;
        join_request_ = "";
        Join(channel);
    }
}

void Connection::OnTextMessageCallback(QString text)
{
    emit (TextMessage(text));
}

PCMAudioFrame* Connection::GetAudioFrame()
{
    QMutexLocker locker(&mutex_playback_queue_);

    if (playback_queue_.size() == 0)
        return 0;

    PCMAudioFrame* frame = playback_queue_.takeFirst();
    return frame;
}

void Connection::SendAudioFrame(PCMAudioFrame* frame)
{
    int audio_quality = 60000;
    int frames_per_packet = 6;

    QMutexLocker locker(&mutex_encode_audio_);

    if (encode_queue_.size() < 100)
        encode_queue_.push_back(frame);
    if (encode_queue_.size() < frames_per_packet)
        return;

    std::deque<std::string> packet_list;
    celt_encoder_ctl(celt_encoder_, CELT_SET_LTP(0));
	//celt_encoder_ctl(celt_encode, CELT_SET_VBR_RATE(audio_quality));

    for (int i = 0; i < frames_per_packet; ++i)
    {
        PCMAudioFrame* audio_frame = encode_queue_.first();
        encode_queue_.pop_front();

        int32_t len = celt_encode(celt_encoder_, reinterpret_cast<short *>(audio_frame->Data()), NULL, encode_buffer_, std::min(audio_quality / (100 * 8), 127));
        packet_list.push_back(std::string(reinterpret_cast<char *>(encode_buffer_), len));

        delete audio_frame;
    }
//    int32_t seq = 0;
    int session = 0;
	char data[1024];
	int flags = 0; // target = 0
	flags |= (MumbleClient::UdpMessageType::UDPVoiceCELTAlpha << 5);
	data[0] = static_cast<unsigned char>(flags);
    PacketDataStream data_stream(data + 1, 1023);
    data_stream << session;
    data_stream << frame_sequence_;

	for (int i = 0; i < frames_per_packet; ++i)
    {
		if (packet_list.empty())
            break;

		const std::string& s = packet_list.front();

		unsigned char head = s.size();
		// Add 0x80 to all but the last frame
		if (i < frames_per_packet - 1)
			head |= 0x80;

		data_stream.append(head);
		data_stream.append(s);

		packet_list.pop_front();
	}
    client_->SendRawUdpTunnel(data, data_stream.size() + 1 );
    frame_sequence_ += frames_per_packet;
}

void Connection::OnChannelAddCallback(const MumbleClient::Channel& channel)
{
    QMutexLocker locker(&mutex_channels_);

    Channel* c = new Channel(channel);
    channels_.append(c);
    QString message = QString("Channel '%1' added").arg(c->Name());
    MumbleVoipModule::LogDebug(message.toStdString());
}

void Connection::OnChannelRemoveCallback(const MumbleClient::Channel& channel)
{
    QMutexLocker locker(&mutex_channels_);

    int i = 0;
    for (int i = 0; i < channels_.size(); ++i)
    {
        if (channels_.at(i)->Id() == channel.id)
        {
            channels_.removeAt(i);
            return;
        }
    }
}

void Connection::OnRawUdpTunnelCallback(int32_t length, void* buffer)
{
    int frames = scanPacket((char*)buffer, length);

    PacketDataStream data_stream = PacketDataStream((char*)buffer, length);
    bool valid = data_stream.isValid();

    uint8_t first_byte = data_stream.next();
    MumbleClient::UdpMessageType::MessageType type = static_cast<MumbleClient::UdpMessageType::MessageType>( ( first_byte >> 5) & 0x07 );
    uint8_t flags = first_byte & 0x1f;
    switch (type)
    {
    case MumbleClient::UdpMessageType::UDPVoiceCELTAlpha:
        break;
    case MumbleClient::UdpMessageType::UDPPing:
        MumbleVoipModule::LogDebug("MUMBLE-UDP: PING");
        return;
        break;
    case MumbleClient::UdpMessageType::UDPVoiceSpeex:
        MumbleVoipModule::LogDebug("MUMBLE-UDP: Speex");
        return;
        break;
    case MumbleClient::UdpMessageType::UDPVoiceCELTBeta:
        MumbleVoipModule::LogDebug("MUMBLE-UDP: CELT B");
        return;
        break;
    }

    //int skip = pds_int_len(data_stream.charPtr());
    //data_stream.skip(skip);

    //skip = pds_int_len(data_stream.charPtr());
    //data_stream.skip(skip);

    int session;
    int seq;
    data_stream >> session;
    data_stream >> seq;

    bool last_frame = true;
    do
    {
		int header = static_cast<unsigned char>(data_stream.next());
        int frame_size = header & 0x7f;
        last_frame = !(header & 0x80);
        const char* frame_data = data_stream.charPtr();
        data_stream.skip(frame_size);

        HandleIncomingCELTFrame((unsigned char*)frame_data, frame_size);
	} while (!last_frame && data_stream.isValid());

    int bytes_left = data_stream.left();
    if (bytes_left)
    {
        float position[3];
        data_stream >> position[0];
        data_stream >> position[1];
        data_stream >> position[2];
    }
}

QList<QString> Connection::Channels()
{
    QMutexLocker locker(&mutex_channels_);

    QList<QString> channels;
    foreach(Channel* c, channels_)
    {
        channels.append(c->Name());
    }
    return channels;
}

void Connection::SendAudio(bool send)
{
    sending_audio_ = send;
}

bool Connection::SendingAudio()
{
    return sending_audio_;
}

void Connection::HandleIncomingCELTFrame(unsigned char* data, int size)
{
    QMutexLocker locker(&mutex_playback_queue_);

    //celt_mode_info(celt_mode_, ???, sample_rate);
    int sample_count = 480;
    celt_int16_t pcm_data[480];
    int ret = celt_decode(celt_decoder_, data, size, pcm_data);
    switch (ret)
    {
    case CELT_OK:
        {
            if (playback_queue_.size() < 100)
            {
                PCMAudioFrame* audio_frame = new PCMAudioFrame(48000, 16, 1, (char*)pcm_data, 2*480);
                playback_queue_.push_back(audio_frame);
                emit AudioFramesAvailable(this);
            }
            else
            {
                MumbleVoipModule::LogWarning("Drop Mumble audio packet");
                return;
            }
        }
        break;
    case CELT_BAD_ARG:
        break;
    case CELT_INVALID_MODE:
        break;
    case CELT_INTERNAL_ERROR:
        break;
    case CELT_CORRUPTED_DATA:
        break;
    case CELT_UNIMPLEMENTED:
        break;
    }
}

} // namespace MumbleVoip
<|endoftext|>


<commit_before>#include <boost/math/special_functions/next.hpp>
#include <boost/random.hpp>

#include <limits>

#include "caffe/common.hpp"
#include "caffe/util/math_functions.hpp"
#include "caffe/util/rng.hpp"

namespace caffe {

template<>
void caffe_cpu_gemm<float>(const CBLAS_TRANSPOSE TransA,
    const CBLAS_TRANSPOSE TransB, const int M, const int N, const int K,
    const float alpha, const float* A, const float* B, const float beta,
    float* C) {
  int lda = (TransA == CblasNoTrans) ? K : M;
  int ldb = (TransB == CblasNoTrans) ? N : K;
  cblas_sgemm(CblasRowMajor, TransA, TransB, M, N, K, alpha, A, lda, B,
      ldb, beta, C, N);
}

template<>
void caffe_cpu_gemm<double>(const CBLAS_TRANSPOSE TransA,
    const CBLAS_TRANSPOSE TransB, const int M, const int N, const int K,
    const double alpha, const double* A, const double* B, const double beta,
    double* C) {
  int lda = (TransA == CblasNoTrans) ? K : M;
  int ldb = (TransB == CblasNoTrans) ? N : K;
  cblas_dgemm(CblasRowMajor, TransA, TransB, M, N, K, alpha, A, lda, B,
      ldb, beta, C, N);
}

template <>
void caffe_cpu_gemv<float>(const CBLAS_TRANSPOSE TransA, const int M,
    const int N, const float alpha, const float* A, const float* x,
    const float beta, float* y) {
  cblas_sgemv(CblasRowMajor, TransA, M, N, alpha, A, N, x, 1, beta, y, 1);
}

template <>
void caffe_cpu_gemv<double>(const CBLAS_TRANSPOSE TransA, const int M,
    const int N, const double alpha, const double* A, const double* x,
    const double beta, double* y) {
  cblas_dgemv(CblasRowMajor, TransA, M, N, alpha, A, N, x, 1, beta, y, 1);
}

template <>
void caffe_axpy<float>(const int N, const float alpha, const float* X,
    float* Y) { cblas_saxpy(N, alpha, X, 1, Y, 1); }

template <>
void caffe_axpy<double>(const int N, const double alpha, const double* X,
    double* Y) { cblas_daxpy(N, alpha, X, 1, Y, 1); }

template <typename Dtype>
void caffe_set(const int N, const Dtype alpha, Dtype* Y) {
  if (alpha == 0) {
    memset(Y, 0, sizeof(Dtype) * N);  // NOLINT(caffe/alt_fn)
    return;
  }
  for (int i = 0; i < N; ++i) {
    Y[i] = alpha;
  }
}

template void caffe_set<int>(const int N, const int alpha, int* Y);
template void caffe_set<float>(const int N, const float alpha, float* Y);
template void caffe_set<double>(const int N, const double alpha, double* Y);

template <>
void caffe_add_scalar(const int N, const float alpha, float* Y) {
  for (int i = 0; i < N; ++i) {
    Y[i] += alpha;
  }
}

template <>
void caffe_add_scalar(const int N, const double alpha, double* Y) {
  for (int i = 0; i < N; ++i) {
    Y[i] += alpha;
  }
}

template <typename Dtype>
void caffe_copy(const int N, const Dtype* X, Dtype* Y) {
  if (X != Y) {
    if (Caffe::mode() == Caffe::GPU) {
#ifndef CPU_ONLY
      // NOLINT_NEXT_LINE(caffe/alt_fn)
      CUDA_CHECK(cudaMemcpy(Y, X, sizeof(Dtype) * N, cudaMemcpyDefault));
#else
      NO_GPU;
#endif
    } else {
      memcpy(Y, X, sizeof(Dtype) * N);  // NOLINT(caffe/alt_fn)
    }
  }
}

template void caffe_copy<int>(const int N, const int* X, int* Y);
template void caffe_copy<unsigned int>(const int N, const unsigned int* X,
    unsigned int* Y);
template void caffe_copy<float>(const int N, const float* X, float* Y);
template void caffe_copy<double>(const int N, const double* X, double* Y);

template <>
void caffe_scal<float>(const int N, const float alpha, float *X) {
  cblas_sscal(N, alpha, X, 1);
}

template <>
void caffe_scal<double>(const int N, const double alpha, double *X) {
  cblas_dscal(N, alpha, X, 1);
}

template <>
void caffe_cpu_axpby<float>(const int N, const float alpha, const float* X,
                            const float beta, float* Y) {
  cblas_saxpby(N, alpha, X, 1, beta, Y, 1);
}

template <>
void caffe_cpu_axpby<double>(const int N, const double alpha, const double* X,
                             const double beta, double* Y) {
  cblas_daxpby(N, alpha, X, 1, beta, Y, 1);
}

template <>
void caffe_add<float>(const int n, const float* a, const float* b,
    float* y) {
  vsAdd(n, a, b, y);
}

template <>
void caffe_add<double>(const int n, const double* a, const double* b,
    double* y) {
  vdAdd(n, a, b, y);
}

template <>
void caffe_sub<float>(const int n, const float* a, const float* b,
    float* y) {
  vsSub(n, a, b, y);
}

template <>
void caffe_sub<double>(const int n, const double* a, const double* b,
    double* y) {
  vdSub(n, a, b, y);
}

template <>
void caffe_mul<float>(const int n, const float* a, const float* b,
    float* y) {
  vsMul(n, a, b, y);
}

template <>
void caffe_mul<double>(const int n, const double* a, const double* b,
    double* y) {
  vdMul(n, a, b, y);
}

template <>
void caffe_div<float>(const int n, const float* a, const float* b,
    float* y) {
  vsDiv(n, a, b, y);
}

template <>
void caffe_div<double>(const int n, const double* a, const double* b,
    double* y) {
  vdDiv(n, a, b, y);
}

template <>
void caffe_powx<float>(const int n, const float* a, const float b,
    float* y) {
  vsPowx(n, a, b, y);
}

template <>
void caffe_powx<double>(const int n, const double* a, const double b,
    double* y) {
  vdPowx(n, a, b, y);
}

template <>
void caffe_sqr<float>(const int n, const float* a, float* y) {
  vsSqr(n, a, y);
}

template <>
void caffe_sqr<double>(const int n, const double* a, double* y) {
  vdSqr(n, a, y);
}

template <>
void caffe_exp<float>(const int n, const float* a, float* y) {
  vsExp(n, a, y);
}

template <>
void caffe_exp<double>(const int n, const double* a, double* y) {
  vdExp(n, a, y);
}

template <>
void caffe_abs<float>(const int n, const float* a, float* y) {
    vsAbs(n, a, y);
}

template <>
void caffe_abs<double>(const int n, const double* a, double* y) {
    vdAbs(n, a, y);
}

unsigned int caffe_rng_rand() {
  return (*caffe_rng())();
}

template <typename Dtype>
Dtype caffe_nextafter(const Dtype b) {
  return boost::math::nextafter<Dtype>(
      b, std::numeric_limits<Dtype>::max());
}

template
float caffe_nextafter(const float b);

template
double caffe_nextafter(const double b);

template <typename Dtype>
void caffe_rng_uniform(const int n, const Dtype a, const Dtype b, Dtype* r) {
  CHECK_GE(n, 0);
  CHECK(r);
  CHECK_LE(a, b);
  boost::uniform_real<Dtype> random_distribution(a, caffe_nextafter<Dtype>(b));
  boost::variate_generator<caffe::rng_t*, boost::uniform_real<Dtype> >
      variate_generator(caffe_rng(), random_distribution);
  for (int i = 0; i < n; ++i) {
    r[i] = variate_generator();
  }
}

template
void caffe_rng_uniform<float>(const int n, const float a, const float b,
                              float* r);

template
void caffe_rng_uniform<double>(const int n, const double a, const double b,
                               double* r);

template <typename Dtype>
void caffe_rng_gaussian(const int n, const Dtype a,
                        const Dtype sigma, Dtype* r) {
  CHECK_GE(n, 0);
  CHECK(r);
  CHECK_GT(sigma, 0);
  boost::normal_distribution<Dtype> random_distribution(a, sigma);
  boost::variate_generator<caffe::rng_t*, boost::normal_distribution<Dtype> >
      variate_generator(caffe_rng(), random_distribution);
  for (int i = 0; i < n; ++i) {
    r[i] = variate_generator();
  }
}

template
void caffe_rng_gaussian<float>(const int n, const float mu,
                               const float sigma, float* r);

template
void caffe_rng_gaussian<double>(const int n, const double mu,
                                const double sigma, double* r);

template <typename Dtype>
void caffe_rng_bernoulli(const int n, const Dtype p, int* r) {
  CHECK_GE(n, 0);
  CHECK(r);
  CHECK_GE(p, 0);
  CHECK_LE(p, 1);
  boost::bernoulli_distribution<Dtype> random_distribution(p);
  boost::variate_generator<caffe::rng_t*, boost::bernoulli_distribution<Dtype> >
      variate_generator(caffe_rng(), random_distribution);
  for (int i = 0; i < n; ++i) {
    r[i] = variate_generator();
  }
}

template
void caffe_rng_bernoulli<double>(const int n, const double p, int* r);

template
void caffe_rng_bernoulli<float>(const int n, const float p, int* r);

template <typename Dtype>
void caffe_rng_bernoulli(const int n, const Dtype p, unsigned int* r) {
  CHECK_GE(n, 0);
  CHECK(r);
  CHECK_GE(p, 0);
  CHECK_LE(p, 1);
  boost::bernoulli_distribution<Dtype> random_distribution(p);
  boost::variate_generator<caffe::rng_t*, boost::bernoulli_distribution<Dtype> >
      variate_generator(caffe_rng(), random_distribution);
  for (int i = 0; i < n; ++i) {
    r[i] = static_cast<unsigned int>(variate_generator());
  }
}

template
void caffe_rng_bernoulli<double>(const int n, const double p, unsigned int* r);

template
void caffe_rng_bernoulli<float>(const int n, const float p, unsigned int* r);

template <typename Dtype>
Dtype caffe_cpu_dot(const int n, const Dtype* x, const Dtype* y) {
  return caffe_cpu_strided_dot(n, x, 1, y, 1);
}

template
float caffe_cpu_dot<float>(const int n, const float* x, const float* y);

template
double caffe_cpu_dot<double>(const int n, const double* x, const double* y);

template <>
float caffe_cpu_strided_dot<float>(const int n, const float* x, const int incx,
    const float* y, const int incy) {
  return cblas_sdot(n, x, incx, y, incy);
}

template <>
double caffe_cpu_strided_dot<double>(const int n, const double* x,
    const int incx, const double* y, const int incy) {
  return cblas_ddot(n, x, incx, y, incy);
}

template <>
int caffe_cpu_hamming_distance<float>(const int n, const float* x,
                                  const float* y) {
  int dist = 0;
  for (int i = 0; i < n; ++i) {
    dist += __builtin_popcount(static_cast<uint32_t>(x[i]) ^
                               static_cast<uint32_t>(y[i]));
  }
  return dist;
}

template <>
int caffe_cpu_hamming_distance<double>(const int n, const double* x,
                                   const double* y) {
  int dist = 0;
  for (int i = 0; i < n; ++i) {
    dist += __builtin_popcountl(static_cast<uint64_t>(x[i]) ^
                                static_cast<uint64_t>(y[i]));
  }
  return dist;
}

template <>
float caffe_cpu_asum<float>(const int n, const float* x) {
  return cblas_sasum(n, x, 1);
}

template <>
double caffe_cpu_asum<double>(const int n, const double* x) {
  return cblas_dasum(n, x, 1);
}

INSTANTIATE_CAFFE_CPU_UNARY_FUNC(sign);
INSTANTIATE_CAFFE_CPU_UNARY_FUNC(sgnbit);

template <>
void caffe_cpu_scale<float>(const int n, const float alpha, const float *x,
                            float* y) {
  cblas_scopy(n, x, 1, y, 1);
  cblas_sscal(n, alpha, y, 1);
}

template <>
void caffe_cpu_scale<double>(const int n, const double alpha, const double *x,
                             double* y) {
  cblas_dcopy(n, x, 1, y, 1);
  cblas_dscal(n, alpha, y, 1);
}

using std::signbit;
bool caffe_signbit(float arg) {
    return signbit(arg);
}
bool caffe_signbit(double arg) {
    return signbit(arg);
}
bool caffe_signbit(long double arg) {
    return signbit(arg);
}

}  // namespace caffe
<commit_msg>specialize cpu_strided_dot before instantiation to fix clang++ build<commit_after>#include <boost/math/special_functions/next.hpp>
#include <boost/random.hpp>

#include <limits>

#include "caffe/common.hpp"
#include "caffe/util/math_functions.hpp"
#include "caffe/util/rng.hpp"

namespace caffe {

template<>
void caffe_cpu_gemm<float>(const CBLAS_TRANSPOSE TransA,
    const CBLAS_TRANSPOSE TransB, const int M, const int N, const int K,
    const float alpha, const float* A, const float* B, const float beta,
    float* C) {
  int lda = (TransA == CblasNoTrans) ? K : M;
  int ldb = (TransB == CblasNoTrans) ? N : K;
  cblas_sgemm(CblasRowMajor, TransA, TransB, M, N, K, alpha, A, lda, B,
      ldb, beta, C, N);
}

template<>
void caffe_cpu_gemm<double>(const CBLAS_TRANSPOSE TransA,
    const CBLAS_TRANSPOSE TransB, const int M, const int N, const int K,
    const double alpha, const double* A, const double* B, const double beta,
    double* C) {
  int lda = (TransA == CblasNoTrans) ? K : M;
  int ldb = (TransB == CblasNoTrans) ? N : K;
  cblas_dgemm(CblasRowMajor, TransA, TransB, M, N, K, alpha, A, lda, B,
      ldb, beta, C, N);
}

template <>
void caffe_cpu_gemv<float>(const CBLAS_TRANSPOSE TransA, const int M,
    const int N, const float alpha, const float* A, const float* x,
    const float beta, float* y) {
  cblas_sgemv(CblasRowMajor, TransA, M, N, alpha, A, N, x, 1, beta, y, 1);
}

template <>
void caffe_cpu_gemv<double>(const CBLAS_TRANSPOSE TransA, const int M,
    const int N, const double alpha, const double* A, const double* x,
    const double beta, double* y) {
  cblas_dgemv(CblasRowMajor, TransA, M, N, alpha, A, N, x, 1, beta, y, 1);
}

template <>
void caffe_axpy<float>(const int N, const float alpha, const float* X,
    float* Y) { cblas_saxpy(N, alpha, X, 1, Y, 1); }

template <>
void caffe_axpy<double>(const int N, const double alpha, const double* X,
    double* Y) { cblas_daxpy(N, alpha, X, 1, Y, 1); }

template <typename Dtype>
void caffe_set(const int N, const Dtype alpha, Dtype* Y) {
  if (alpha == 0) {
    memset(Y, 0, sizeof(Dtype) * N);  // NOLINT(caffe/alt_fn)
    return;
  }
  for (int i = 0; i < N; ++i) {
    Y[i] = alpha;
  }
}

template void caffe_set<int>(const int N, const int alpha, int* Y);
template void caffe_set<float>(const int N, const float alpha, float* Y);
template void caffe_set<double>(const int N, const double alpha, double* Y);

template <>
void caffe_add_scalar(const int N, const float alpha, float* Y) {
  for (int i = 0; i < N; ++i) {
    Y[i] += alpha;
  }
}

template <>
void caffe_add_scalar(const int N, const double alpha, double* Y) {
  for (int i = 0; i < N; ++i) {
    Y[i] += alpha;
  }
}

template <typename Dtype>
void caffe_copy(const int N, const Dtype* X, Dtype* Y) {
  if (X != Y) {
    if (Caffe::mode() == Caffe::GPU) {
#ifndef CPU_ONLY
      // NOLINT_NEXT_LINE(caffe/alt_fn)
      CUDA_CHECK(cudaMemcpy(Y, X, sizeof(Dtype) * N, cudaMemcpyDefault));
#else
      NO_GPU;
#endif
    } else {
      memcpy(Y, X, sizeof(Dtype) * N);  // NOLINT(caffe/alt_fn)
    }
  }
}

template void caffe_copy<int>(const int N, const int* X, int* Y);
template void caffe_copy<unsigned int>(const int N, const unsigned int* X,
    unsigned int* Y);
template void caffe_copy<float>(const int N, const float* X, float* Y);
template void caffe_copy<double>(const int N, const double* X, double* Y);

template <>
void caffe_scal<float>(const int N, const float alpha, float *X) {
  cblas_sscal(N, alpha, X, 1);
}

template <>
void caffe_scal<double>(const int N, const double alpha, double *X) {
  cblas_dscal(N, alpha, X, 1);
}

template <>
void caffe_cpu_axpby<float>(const int N, const float alpha, const float* X,
                            const float beta, float* Y) {
  cblas_saxpby(N, alpha, X, 1, beta, Y, 1);
}

template <>
void caffe_cpu_axpby<double>(const int N, const double alpha, const double* X,
                             const double beta, double* Y) {
  cblas_daxpby(N, alpha, X, 1, beta, Y, 1);
}

template <>
void caffe_add<float>(const int n, const float* a, const float* b,
    float* y) {
  vsAdd(n, a, b, y);
}

template <>
void caffe_add<double>(const int n, const double* a, const double* b,
    double* y) {
  vdAdd(n, a, b, y);
}

template <>
void caffe_sub<float>(const int n, const float* a, const float* b,
    float* y) {
  vsSub(n, a, b, y);
}

template <>
void caffe_sub<double>(const int n, const double* a, const double* b,
    double* y) {
  vdSub(n, a, b, y);
}

template <>
void caffe_mul<float>(const int n, const float* a, const float* b,
    float* y) {
  vsMul(n, a, b, y);
}

template <>
void caffe_mul<double>(const int n, const double* a, const double* b,
    double* y) {
  vdMul(n, a, b, y);
}

template <>
void caffe_div<float>(const int n, const float* a, const float* b,
    float* y) {
  vsDiv(n, a, b, y);
}

template <>
void caffe_div<double>(const int n, const double* a, const double* b,
    double* y) {
  vdDiv(n, a, b, y);
}

template <>
void caffe_powx<float>(const int n, const float* a, const float b,
    float* y) {
  vsPowx(n, a, b, y);
}

template <>
void caffe_powx<double>(const int n, const double* a, const double b,
    double* y) {
  vdPowx(n, a, b, y);
}

template <>
void caffe_sqr<float>(const int n, const float* a, float* y) {
  vsSqr(n, a, y);
}

template <>
void caffe_sqr<double>(const int n, const double* a, double* y) {
  vdSqr(n, a, y);
}

template <>
void caffe_exp<float>(const int n, const float* a, float* y) {
  vsExp(n, a, y);
}

template <>
void caffe_exp<double>(const int n, const double* a, double* y) {
  vdExp(n, a, y);
}

template <>
void caffe_abs<float>(const int n, const float* a, float* y) {
    vsAbs(n, a, y);
}

template <>
void caffe_abs<double>(const int n, const double* a, double* y) {
    vdAbs(n, a, y);
}

unsigned int caffe_rng_rand() {
  return (*caffe_rng())();
}

template <typename Dtype>
Dtype caffe_nextafter(const Dtype b) {
  return boost::math::nextafter<Dtype>(
      b, std::numeric_limits<Dtype>::max());
}

template
float caffe_nextafter(const float b);

template
double caffe_nextafter(const double b);

template <typename Dtype>
void caffe_rng_uniform(const int n, const Dtype a, const Dtype b, Dtype* r) {
  CHECK_GE(n, 0);
  CHECK(r);
  CHECK_LE(a, b);
  boost::uniform_real<Dtype> random_distribution(a, caffe_nextafter<Dtype>(b));
  boost::variate_generator<caffe::rng_t*, boost::uniform_real<Dtype> >
      variate_generator(caffe_rng(), random_distribution);
  for (int i = 0; i < n; ++i) {
    r[i] = variate_generator();
  }
}

template
void caffe_rng_uniform<float>(const int n, const float a, const float b,
                              float* r);

template
void caffe_rng_uniform<double>(const int n, const double a, const double b,
                               double* r);

template <typename Dtype>
void caffe_rng_gaussian(const int n, const Dtype a,
                        const Dtype sigma, Dtype* r) {
  CHECK_GE(n, 0);
  CHECK(r);
  CHECK_GT(sigma, 0);
  boost::normal_distribution<Dtype> random_distribution(a, sigma);
  boost::variate_generator<caffe::rng_t*, boost::normal_distribution<Dtype> >
      variate_generator(caffe_rng(), random_distribution);
  for (int i = 0; i < n; ++i) {
    r[i] = variate_generator();
  }
}

template
void caffe_rng_gaussian<float>(const int n, const float mu,
                               const float sigma, float* r);

template
void caffe_rng_gaussian<double>(const int n, const double mu,
                                const double sigma, double* r);

template <typename Dtype>
void caffe_rng_bernoulli(const int n, const Dtype p, int* r) {
  CHECK_GE(n, 0);
  CHECK(r);
  CHECK_GE(p, 0);
  CHECK_LE(p, 1);
  boost::bernoulli_distribution<Dtype> random_distribution(p);
  boost::variate_generator<caffe::rng_t*, boost::bernoulli_distribution<Dtype> >
      variate_generator(caffe_rng(), random_distribution);
  for (int i = 0; i < n; ++i) {
    r[i] = variate_generator();
  }
}

template
void caffe_rng_bernoulli<double>(const int n, const double p, int* r);

template
void caffe_rng_bernoulli<float>(const int n, const float p, int* r);

template <typename Dtype>
void caffe_rng_bernoulli(const int n, const Dtype p, unsigned int* r) {
  CHECK_GE(n, 0);
  CHECK(r);
  CHECK_GE(p, 0);
  CHECK_LE(p, 1);
  boost::bernoulli_distribution<Dtype> random_distribution(p);
  boost::variate_generator<caffe::rng_t*, boost::bernoulli_distribution<Dtype> >
      variate_generator(caffe_rng(), random_distribution);
  for (int i = 0; i < n; ++i) {
    r[i] = static_cast<unsigned int>(variate_generator());
  }
}

template
void caffe_rng_bernoulli<double>(const int n, const double p, unsigned int* r);

template
void caffe_rng_bernoulli<float>(const int n, const float p, unsigned int* r);

template <>
float caffe_cpu_strided_dot<float>(const int n, const float* x, const int incx,
    const float* y, const int incy) {
  return cblas_sdot(n, x, incx, y, incy);
}

template <>
double caffe_cpu_strided_dot<double>(const int n, const double* x,
    const int incx, const double* y, const int incy) {
  return cblas_ddot(n, x, incx, y, incy);
}

template <typename Dtype>
Dtype caffe_cpu_dot(const int n, const Dtype* x, const Dtype* y) {
  return caffe_cpu_strided_dot(n, x, 1, y, 1);
}

template
float caffe_cpu_dot<float>(const int n, const float* x, const float* y);

template
double caffe_cpu_dot<double>(const int n, const double* x, const double* y);

template <>
int caffe_cpu_hamming_distance<float>(const int n, const float* x,
                                  const float* y) {
  int dist = 0;
  for (int i = 0; i < n; ++i) {
    dist += __builtin_popcount(static_cast<uint32_t>(x[i]) ^
                               static_cast<uint32_t>(y[i]));
  }
  return dist;
}

template <>
int caffe_cpu_hamming_distance<double>(const int n, const double* x,
                                   const double* y) {
  int dist = 0;
  for (int i = 0; i < n; ++i) {
    dist += __builtin_popcountl(static_cast<uint64_t>(x[i]) ^
                                static_cast<uint64_t>(y[i]));
  }
  return dist;
}

template <>
float caffe_cpu_asum<float>(const int n, const float* x) {
  return cblas_sasum(n, x, 1);
}

template <>
double caffe_cpu_asum<double>(const int n, const double* x) {
  return cblas_dasum(n, x, 1);
}

INSTANTIATE_CAFFE_CPU_UNARY_FUNC(sign);
INSTANTIATE_CAFFE_CPU_UNARY_FUNC(sgnbit);

template <>
void caffe_cpu_scale<float>(const int n, const float alpha, const float *x,
                            float* y) {
  cblas_scopy(n, x, 1, y, 1);
  cblas_sscal(n, alpha, y, 1);
}

template <>
void caffe_cpu_scale<double>(const int n, const double alpha, const double *x,
                             double* y) {
  cblas_dcopy(n, x, 1, y, 1);
  cblas_dscal(n, alpha, y, 1);
}

using std::signbit;
bool caffe_signbit(float arg) {
    return signbit(arg);
}
bool caffe_signbit(double arg) {
    return signbit(arg);
}
bool caffe_signbit(long double arg) {
    return signbit(arg);
}

}  // namespace caffe
<|endoftext|>


<commit_before>#include "CPlusPlusMangle.h"

#include "LLVM_Headers.h"
#include <clang/AST/ASTContext.h>
#include <clang/AST/DeclCXX.h>
#include <clang/AST/Mangle.h>
#include <clang/Basic/Builtins.h>
#include <clang/Basic/TargetInfo.h>
#include <clang/Frontend/CompilerInstance.h>
#include "IR.h"
#include "Type.h"

namespace Halide {

namespace Internal {

namespace {

clang::DeclContext *namespaced_decl_scope(clang::ASTContext &context, const std::vector<std::string> &namespaces) {
    clang::DeclContext *decl_context = context.getTranslationUnitDecl();
    for (const auto &namespace_name : namespaces) {
        decl_context = clang::NamespaceDecl::Create(context, decl_context, false, clang::SourceLocation(), clang::SourceLocation(),
                                                    &context.Idents.get(namespace_name), NULL);
    }
    return decl_context;
}

clang::TagDecl::TagKind map_tag_decl_kind(halide_cplusplus_type_name::CPPTypeType halide_val) {
    switch (halide_val) {
    case halide_cplusplus_type_name::Simple:
        internal_error << "Simple types should have already been handled.\n";
    case halide_cplusplus_type_name::Struct:
        return clang::TTK_Struct;
    case halide_cplusplus_type_name::Class:
        return clang::TTK_Class;
    case halide_cplusplus_type_name::Union:
        return clang::TTK_Union;
    case halide_cplusplus_type_name::Enum:
        return clang::TTK_Enum;
    }
}

struct PreviousDeclarations {
    struct class_or_struct {
        halide_cplusplus_type_name::CPPTypeType cpp_type_type;
        clang::CXXRecordDecl *decl{nullptr};
    };
    std::map<std::string, class_or_struct> classes_and_structs;

    std::map<std::string, clang::EnumDecl *> enums;

    clang::CXXRecordDecl *DeclareRecord(clang::ASTContext &context, clang::DeclContext *decl_context,
                                        const halide_cplusplus_type_name &inner_name) {
        class_or_struct &entry(classes_and_structs[inner_name.name]);
        if (entry.decl != nullptr) {
            const char *map_to_name[] { "simple (unexpected", "struct", "class", "union", "enum (unexpected)" };
            user_assert(entry.cpp_type_type == inner_name.cpp_type_type) << "C++ type info for " << inner_name.name << " originally declared as " <<
                map_to_name[entry.cpp_type_type] << " and redeclared as " << map_to_name[inner_name.cpp_type_type] << ".\n";
        } else {
            entry. decl = clang::CXXRecordDecl::Create(context, map_tag_decl_kind(inner_name.cpp_type_type),
                                                       decl_context, clang::SourceLocation(), clang::SourceLocation(),
                                                       &context.Idents.get(inner_name.name))->getCanonicalDecl();
            entry.cpp_type_type = inner_name.cpp_type_type;
      }
      return entry.decl;
    }

    clang::EnumDecl *DeclareEnum(clang::ASTContext &context, clang::DeclContext *decl_context,
                                 const halide_cplusplus_type_name &inner_name) {
        clang::EnumDecl *&entry(enums[inner_name.name]);
        if (entry == nullptr) {
            entry = clang::EnumDecl::Create(context, decl_context,
                                            clang::SourceLocation(), clang::SourceLocation(),
                                            &context.Idents.get(inner_name.name),
                                            NULL, false, false, false)->getCanonicalDecl();
        }
        return entry;
    }
};

clang::QualType halide_type_to_clang_type(clang::ASTContext &context, PreviousDeclarations &prev_decls, Type type) {
    if (type.is_int()) {
        // TODO: Figure out how to resolve whether platform dependent 64-bit type is long or long long.
        if (type.bits() == 64) {
            return context.LongLongTy;
        } else {
            return context.getIntTypeForBitwidth(type.bits(), true);
        }
    } else if (type.is_uint()) {
        if (type.bits() == 1) {
            return context.BoolTy;
        } else if (type.bits() == 64) {
            return context.UnsignedLongLongTy;
        } else {
          return context.getIntTypeForBitwidth(type.bits(), false);
        }
    } else if (type.is_float()) {
        return context.getRealTypeForBitwidth(type.bits());
    } else {
        internal_assert(type.is_handle()) << "New type of Type that isn't handled.\n";

        clang::QualType base_type;
        if (type.handle_type != NULL) {
            if (type.handle_type->inner_name.cpp_type_type == halide_cplusplus_type_name::Simple) {
                user_assert(type.handle_type->namespaces.empty() && type.handle_type->enclosing_types.empty()) <<
                    "Simple handle type cannot be inside any namespace or type scopes.\n";

                // Only handle explicitly sized types per Halide convention.
                if (type.handle_type->inner_name.name == "void") {
                    base_type = context.VoidTy;
                } else if (type.handle_type->inner_name.name == "bool") {
                    base_type = context.BoolTy;
                } else if (type.handle_type->inner_name.name == "int8_t") {
                    base_type = context.getIntTypeForBitwidth(8, true);
                } else if (type.handle_type->inner_name.name == "int16_t") {
                    base_type = context.getIntTypeForBitwidth(16, true);
                } else if (type.handle_type->inner_name.name == "int32_t") {
                    base_type = context.getIntTypeForBitwidth(32, true);
                } else if (type.handle_type->inner_name.name == "int64_t") {
                    base_type = context.LongLongTy;
                } else if (type.handle_type->inner_name.name == "uint8_t") {
                    base_type = context.getIntTypeForBitwidth(8, false);
                } else if (type.handle_type->inner_name.name == "uint16_t") {
                    base_type = context.getIntTypeForBitwidth(16, false);
                } else if (type.handle_type->inner_name.name == "uint32_t") {
                    base_type = context.getIntTypeForBitwidth(32, false);
                } else if (type.handle_type->inner_name.name == "uint64_t") {
                    base_type = context.UnsignedLongLongTy;
                } else if (type.handle_type->inner_name.name == "half") { // TODO: decide if this is a good idea
                    base_type = context.getRealTypeForBitwidth(16);
                } else if (type.handle_type->inner_name.name == "float") {
                    base_type = context.getRealTypeForBitwidth(32);
                } else if (type.handle_type->inner_name.name == "double") {
                    base_type = context.getRealTypeForBitwidth(64);
                } else {
                    user_error << "Unknown simple handle type " << type.handle_type->inner_name.name << "\n";
                }
            } else {
                clang::DeclContext *decl_context = namespaced_decl_scope(context, type.handle_type->namespaces);
                for (auto &scope_inner_name : type.handle_type->enclosing_types) {
                    user_assert(scope_inner_name.cpp_type_type != halide_cplusplus_type_name::Enum) <<
                        "Enums canot scope other types. (Enum name is " << scope_inner_name.name << ")\n";
                    decl_context = prev_decls.DeclareRecord(context, decl_context, scope_inner_name);
                }

                if (type.handle_type->inner_name.cpp_type_type == halide_cplusplus_type_name::Enum) {
                    base_type = context.getEnumType(prev_decls.DeclareEnum(context, decl_context, type.handle_type->inner_name));
                } else {
                    base_type = context.getRecordType(prev_decls.DeclareRecord(context, decl_context, type.handle_type->inner_name));
                }
            }

            for (uint8_t modifier : type.handle_type->cpp_type_modifiers) {
                if (modifier & halide_handle_cplusplus_type::Const) {
                    base_type.addConst();
                }
                if (modifier & halide_handle_cplusplus_type::Volatile) {
                    base_type.addVolatile();
                }
                if (modifier & halide_handle_cplusplus_type::Restrict) {
                    base_type.addRestrict();
                }
                if (modifier & halide_handle_cplusplus_type::Pointer) {
                    base_type = context.getPointerType(base_type);
                } else {
                    break;
                }
            }

            if (type.handle_type->reference_type == halide_handle_cplusplus_type::LValueReference) {
                    base_type = context.getLValueReferenceType(base_type);
            } else if (type.handle_type->reference_type == halide_handle_cplusplus_type::LValueReference) {
                    base_type = context.getRValueReferenceType(base_type);
            }

            return base_type;
        }
        // Otherwise return void *
    }
    return context.VoidPtrTy;
}

}

std::string cplusplus_function_mangled_name(const std::string &name, const std::vector<std::string> &namespaces,
                                            Type return_type, const std::vector<ExternFuncArgument> &args,
                                            const Target &target) {
    clang::CompilerInstance compiler_instance;

    compiler_instance.createDiagnostics();
    std::shared_ptr<clang::TargetOptions> target_options(new clang::TargetOptions);

    // Not sure this is necessary given the MangleContext creation
    // below, but just in case. Note handling of mapping of integer
    // types is likely platform dependent. E.g. int64_t could map to
    // long or to long long depending on the platform and these mangle
    // differently.
    if (target.os == Target::Windows) {
        // Have to provide something so compilation is independent of host platform
        target_options->Triple = "x86_64-unknown-unknown-unknown";
    } else {
        target_options->Triple = "x86_64-unknown-win32-msvc";
    }
    compiler_instance.setTarget(clang::TargetInfo::CreateTargetInfo(compiler_instance.getDiagnostics(), target_options));
    compiler_instance.createFileManager();
    compiler_instance.createSourceManager(compiler_instance.getFileManager());
    compiler_instance.getLangOpts().CPlusPlus = true;
    compiler_instance.getLangOpts().CPlusPlus11 = true;
    compiler_instance.createPreprocessor(clang::TU_Complete);
    compiler_instance.createASTContext();

    clang::DiagnosticsEngine &diags(compiler_instance.getDiagnostics());
    clang::ASTContext &context(compiler_instance.getASTContext());

    std::unique_ptr<clang::MangleContext> mangle_context;
    if (target.os == Target::Windows) {
        mangle_context.reset(clang::MicrosoftMangleContext::create(context, diags));
    } else {
        mangle_context.reset(clang::ItaniumMangleContext::create(context, diags));
    }

    clang::DeclContext *decl_context = namespaced_decl_scope(context, namespaces);
    PreviousDeclarations prev_decls;

    std::vector<clang::QualType> clang_args;
    for (auto &arg : args) {
        clang_args.push_back(halide_type_to_clang_type(context, prev_decls,
                                                       arg.is_expr() ? arg.expr.type()
                                                                     : type_of<struct buffer_t *>()));
    }

    clang::QualType clang_return_type = halide_type_to_clang_type(context, prev_decls, return_type);
    clang::QualType function_type = context.getFunctionType(clang_return_type, clang_args,
                                                            clang::FunctionProtoType::ExtProtoInfo());
    clang::FunctionDecl *decl = clang::FunctionDecl::Create(context, decl_context,
                                                            clang::SourceLocation(), clang::SourceLocation(),
                                                            &context.Idents.get(name), function_type, NULL, clang::SC_None);
    std::vector<clang::ParmVarDecl *> param_var_decls;
    for (auto &qual_type : clang_args) {
        param_var_decls.push_back(clang::ParmVarDecl::Create(context, decl,
                                                             clang::SourceLocation(), clang::SourceLocation(),
                                                             NULL, qual_type, NULL, clang::SC_None, NULL));
    }
    decl->setParams(param_var_decls);

    const clang::FunctionType *ft = decl->getType()->getAs<clang::FunctionType>();
    const clang::FunctionProtoType *proto = clang::cast<clang::FunctionProtoType>(ft);
    internal_assert(proto != NULL) << "proto is null\n";

    std::string result;
    llvm::raw_string_ostream out_str(result);
    mangle_context->mangleName(decl, out_str);

    return out_str.str();
}

void cplusplus_mangle_test() {
    std::string simple_name =
        cplusplus_function_mangled_name("test_function", { }, Int(32), { }, Target(Target::Linux, Target::X86, 64));
    internal_assert(simple_name == "_Z13test_functionv") << "Expected mangling  for simple canse to produce _Z13test_functionv but got " << simple_name << "\n";
    std::string with_namespaces =
        cplusplus_function_mangled_name("test_function", { "foo", "bar" }, Int(32), { }, Target(Target::Linux, Target::X86, 64));
    internal_assert(with_namespaces == "_ZN3foo3bar13test_functionEv") << "Expected mangling namespace case to produce _ZN3foo3bar13test_functionEv but got " << simple_name << "\n";
    std::string with_args =
      cplusplus_function_mangled_name("test_function", { "foo", "bar" }, Int(32), { ExternFuncArgument(42) }, Target(Target::Linux, Target::X86, 64));
    internal_assert(with_args == "_ZN3foo3bar13test_functionEi") << "Expected mangling args case to produce _ZN3foo3bar13test_functionEi but got " << simple_name << "\n";
    // TODO: test struct types, Microsoft mangling.
}

}

}
<commit_msg>Fix return path issue witht ag mapping.<commit_after>#include "CPlusPlusMangle.h"

#include "LLVM_Headers.h"
#include <clang/AST/ASTContext.h>
#include <clang/AST/DeclCXX.h>
#include <clang/AST/Mangle.h>
#include <clang/Basic/Builtins.h>
#include <clang/Basic/TargetInfo.h>
#include <clang/Frontend/CompilerInstance.h>
#include "IR.h"
#include "Type.h"

namespace Halide {

namespace Internal {

namespace {

clang::DeclContext *namespaced_decl_scope(clang::ASTContext &context, const std::vector<std::string> &namespaces) {
    clang::DeclContext *decl_context = context.getTranslationUnitDecl();
    for (const auto &namespace_name : namespaces) {
        decl_context = clang::NamespaceDecl::Create(context, decl_context, false, clang::SourceLocation(), clang::SourceLocation(),
                                                    &context.Idents.get(namespace_name), NULL);
    }
    return decl_context;
}

clang::TagDecl::TagKind map_tag_decl_kind(halide_cplusplus_type_name::CPPTypeType halide_val) {
    switch (halide_val) {
    case halide_cplusplus_type_name::Simple:
        internal_error << "Simple types should have already been handled.\n";
	return clang::TTK_Struct; // Have to return here to avoid unknown case below.
    case halide_cplusplus_type_name::Struct:
        return clang::TTK_Struct;
    case halide_cplusplus_type_name::Class:
        return clang::TTK_Class;
    case halide_cplusplus_type_name::Union:
        return clang::TTK_Union;
    case halide_cplusplus_type_name::Enum:
        return clang::TTK_Enum;
    }
    internal_error << "Unknown halide_cplusplus_type_name::CPPTypeType.\n";
    return clang::TTK_Struct; // Avoid control flow analysis error.
}

struct PreviousDeclarations {
    struct class_or_struct {
        halide_cplusplus_type_name::CPPTypeType cpp_type_type;
        clang::CXXRecordDecl *decl{nullptr};
    };
    std::map<std::string, class_or_struct> classes_and_structs;

    std::map<std::string, clang::EnumDecl *> enums;

    clang::CXXRecordDecl *DeclareRecord(clang::ASTContext &context, clang::DeclContext *decl_context,
                                        const halide_cplusplus_type_name &inner_name) {
        class_or_struct &entry(classes_and_structs[inner_name.name]);
        if (entry.decl != nullptr) {
            const char *map_to_name[] { "simple (unexpected", "struct", "class", "union", "enum (unexpected)" };
            user_assert(entry.cpp_type_type == inner_name.cpp_type_type) << "C++ type info for " << inner_name.name << " originally declared as " <<
                map_to_name[entry.cpp_type_type] << " and redeclared as " << map_to_name[inner_name.cpp_type_type] << ".\n";
        } else {
            entry. decl = clang::CXXRecordDecl::Create(context, map_tag_decl_kind(inner_name.cpp_type_type),
                                                       decl_context, clang::SourceLocation(), clang::SourceLocation(),
                                                       &context.Idents.get(inner_name.name))->getCanonicalDecl();
            entry.cpp_type_type = inner_name.cpp_type_type;
      }
      return entry.decl;
    }

    clang::EnumDecl *DeclareEnum(clang::ASTContext &context, clang::DeclContext *decl_context,
                                 const halide_cplusplus_type_name &inner_name) {
        clang::EnumDecl *&entry(enums[inner_name.name]);
        if (entry == nullptr) {
            entry = clang::EnumDecl::Create(context, decl_context,
                                            clang::SourceLocation(), clang::SourceLocation(),
                                            &context.Idents.get(inner_name.name),
                                            NULL, false, false, false)->getCanonicalDecl();
        }
        return entry;
    }
};

clang::QualType halide_type_to_clang_type(clang::ASTContext &context, PreviousDeclarations &prev_decls, Type type) {
    if (type.is_int()) {
        // TODO: Figure out how to resolve whether platform dependent 64-bit type is long or long long.
        if (type.bits() == 64) {
            return context.LongLongTy;
        } else {
            return context.getIntTypeForBitwidth(type.bits(), true);
        }
    } else if (type.is_uint()) {
        if (type.bits() == 1) {
            return context.BoolTy;
        } else if (type.bits() == 64) {
            return context.UnsignedLongLongTy;
        } else {
          return context.getIntTypeForBitwidth(type.bits(), false);
        }
    } else if (type.is_float()) {
        return context.getRealTypeForBitwidth(type.bits());
    } else {
        internal_assert(type.is_handle()) << "New type of Type that isn't handled.\n";

        clang::QualType base_type;
        if (type.handle_type != NULL) {
            if (type.handle_type->inner_name.cpp_type_type == halide_cplusplus_type_name::Simple) {
                user_assert(type.handle_type->namespaces.empty() && type.handle_type->enclosing_types.empty()) <<
                    "Simple handle type cannot be inside any namespace or type scopes.\n";

                // Only handle explicitly sized types per Halide convention.
                if (type.handle_type->inner_name.name == "void") {
                    base_type = context.VoidTy;
                } else if (type.handle_type->inner_name.name == "bool") {
                    base_type = context.BoolTy;
                } else if (type.handle_type->inner_name.name == "int8_t") {
                    base_type = context.getIntTypeForBitwidth(8, true);
                } else if (type.handle_type->inner_name.name == "int16_t") {
                    base_type = context.getIntTypeForBitwidth(16, true);
                } else if (type.handle_type->inner_name.name == "int32_t") {
                    base_type = context.getIntTypeForBitwidth(32, true);
                } else if (type.handle_type->inner_name.name == "int64_t") {
                    base_type = context.LongLongTy;
                } else if (type.handle_type->inner_name.name == "uint8_t") {
                    base_type = context.getIntTypeForBitwidth(8, false);
                } else if (type.handle_type->inner_name.name == "uint16_t") {
                    base_type = context.getIntTypeForBitwidth(16, false);
                } else if (type.handle_type->inner_name.name == "uint32_t") {
                    base_type = context.getIntTypeForBitwidth(32, false);
                } else if (type.handle_type->inner_name.name == "uint64_t") {
                    base_type = context.UnsignedLongLongTy;
                } else if (type.handle_type->inner_name.name == "half") { // TODO: decide if this is a good idea
                    base_type = context.getRealTypeForBitwidth(16);
                } else if (type.handle_type->inner_name.name == "float") {
                    base_type = context.getRealTypeForBitwidth(32);
                } else if (type.handle_type->inner_name.name == "double") {
                    base_type = context.getRealTypeForBitwidth(64);
                } else {
                    user_error << "Unknown simple handle type " << type.handle_type->inner_name.name << "\n";
                }
            } else {
                clang::DeclContext *decl_context = namespaced_decl_scope(context, type.handle_type->namespaces);
                for (auto &scope_inner_name : type.handle_type->enclosing_types) {
                    user_assert(scope_inner_name.cpp_type_type != halide_cplusplus_type_name::Enum) <<
                        "Enums canot scope other types. (Enum name is " << scope_inner_name.name << ")\n";
                    decl_context = prev_decls.DeclareRecord(context, decl_context, scope_inner_name);
                }

                if (type.handle_type->inner_name.cpp_type_type == halide_cplusplus_type_name::Enum) {
                    base_type = context.getEnumType(prev_decls.DeclareEnum(context, decl_context, type.handle_type->inner_name));
                } else {
                    base_type = context.getRecordType(prev_decls.DeclareRecord(context, decl_context, type.handle_type->inner_name));
                }
            }

            for (uint8_t modifier : type.handle_type->cpp_type_modifiers) {
                if (modifier & halide_handle_cplusplus_type::Const) {
                    base_type.addConst();
                }
                if (modifier & halide_handle_cplusplus_type::Volatile) {
                    base_type.addVolatile();
                }
                if (modifier & halide_handle_cplusplus_type::Restrict) {
                    base_type.addRestrict();
                }
                if (modifier & halide_handle_cplusplus_type::Pointer) {
                    base_type = context.getPointerType(base_type);
                } else {
                    break;
                }
            }

            if (type.handle_type->reference_type == halide_handle_cplusplus_type::LValueReference) {
                    base_type = context.getLValueReferenceType(base_type);
            } else if (type.handle_type->reference_type == halide_handle_cplusplus_type::LValueReference) {
                    base_type = context.getRValueReferenceType(base_type);
            }

            return base_type;
        }
        // Otherwise return void *
    }
    return context.VoidPtrTy;
}

}

std::string cplusplus_function_mangled_name(const std::string &name, const std::vector<std::string> &namespaces,
                                            Type return_type, const std::vector<ExternFuncArgument> &args,
                                            const Target &target) {
    clang::CompilerInstance compiler_instance;

    compiler_instance.createDiagnostics();
    std::shared_ptr<clang::TargetOptions> target_options(new clang::TargetOptions);

    // Not sure this is necessary given the MangleContext creation
    // below, but just in case. Note handling of mapping of integer
    // types is likely platform dependent. E.g. int64_t could map to
    // long or to long long depending on the platform and these mangle
    // differently.
    if (target.os == Target::Windows) {
        // Have to provide something so compilation is independent of host platform
        target_options->Triple = "x86_64-unknown-unknown-unknown";
    } else {
        target_options->Triple = "x86_64-unknown-win32-msvc";
    }
    compiler_instance.setTarget(clang::TargetInfo::CreateTargetInfo(compiler_instance.getDiagnostics(), target_options));
    compiler_instance.createFileManager();
    compiler_instance.createSourceManager(compiler_instance.getFileManager());
    compiler_instance.getLangOpts().CPlusPlus = true;
    compiler_instance.getLangOpts().CPlusPlus11 = true;
    compiler_instance.createPreprocessor(clang::TU_Complete);
    compiler_instance.createASTContext();

    clang::DiagnosticsEngine &diags(compiler_instance.getDiagnostics());
    clang::ASTContext &context(compiler_instance.getASTContext());

    std::unique_ptr<clang::MangleContext> mangle_context;
    if (target.os == Target::Windows) {
        mangle_context.reset(clang::MicrosoftMangleContext::create(context, diags));
    } else {
        mangle_context.reset(clang::ItaniumMangleContext::create(context, diags));
    }

    clang::DeclContext *decl_context = namespaced_decl_scope(context, namespaces);
    PreviousDeclarations prev_decls;

    std::vector<clang::QualType> clang_args;
    for (auto &arg : args) {
        clang_args.push_back(halide_type_to_clang_type(context, prev_decls,
                                                       arg.is_expr() ? arg.expr.type()
                                                                     : type_of<struct buffer_t *>()));
    }

    clang::QualType clang_return_type = halide_type_to_clang_type(context, prev_decls, return_type);
    clang::QualType function_type = context.getFunctionType(clang_return_type, clang_args,
                                                            clang::FunctionProtoType::ExtProtoInfo());
    clang::FunctionDecl *decl = clang::FunctionDecl::Create(context, decl_context,
                                                            clang::SourceLocation(), clang::SourceLocation(),
                                                            &context.Idents.get(name), function_type, NULL, clang::SC_None);
    std::vector<clang::ParmVarDecl *> param_var_decls;
    for (auto &qual_type : clang_args) {
        param_var_decls.push_back(clang::ParmVarDecl::Create(context, decl,
                                                             clang::SourceLocation(), clang::SourceLocation(),
                                                             NULL, qual_type, NULL, clang::SC_None, NULL));
    }
    decl->setParams(param_var_decls);

    const clang::FunctionType *ft = decl->getType()->getAs<clang::FunctionType>();
    const clang::FunctionProtoType *proto = clang::cast<clang::FunctionProtoType>(ft);
    internal_assert(proto != NULL) << "proto is null\n";

    std::string result;
    llvm::raw_string_ostream out_str(result);
    mangle_context->mangleName(decl, out_str);

    return out_str.str();
}

void cplusplus_mangle_test() {
    std::string simple_name =
        cplusplus_function_mangled_name("test_function", { }, Int(32), { }, Target(Target::Linux, Target::X86, 64));
    internal_assert(simple_name == "_Z13test_functionv") << "Expected mangling  for simple canse to produce _Z13test_functionv but got " << simple_name << "\n";
    std::string with_namespaces =
        cplusplus_function_mangled_name("test_function", { "foo", "bar" }, Int(32), { }, Target(Target::Linux, Target::X86, 64));
    internal_assert(with_namespaces == "_ZN3foo3bar13test_functionEv") << "Expected mangling namespace case to produce _ZN3foo3bar13test_functionEv but got " << simple_name << "\n";
    std::string with_args =
      cplusplus_function_mangled_name("test_function", { "foo", "bar" }, Int(32), { ExternFuncArgument(42) }, Target(Target::Linux, Target::X86, 64));
    internal_assert(with_args == "_ZN3foo3bar13test_functionEi") << "Expected mangling args case to produce _ZN3foo3bar13test_functionEi but got " << simple_name << "\n";
    // TODO: test struct types, Microsoft mangling.
}

}

}
<|endoftext|>


<commit_before>/*******************************************************************************
GPU OPTIMIZED MONTE CARLO (GOMC) 2.70
Copyright (C) 2018  GOMC Group
A copy of the GNU General Public License can be found in the COPYRIGHT.txt
along with this program, also can be found at <http://www.gnu.org/licenses/>.
********************************************************************************/

#include <stdint.h>
#include "CheckpointSetup.h"

CheckpointSetup::CheckpointSetup(ulong & startStep,
                                ulong & trueStep,
                                MoleculeLookup & molLookup,
                                MoveSettings & moveSettings,
                                Molecules & mol,
                                PRNG & prng,
                                Random123Wrapper & r123,
                                Setup & set) :
  molLookupRef(molLookup), moveSetRef(moveSettings), molRef(mol), prngRef(prng),
  r123Ref(r123), startStepRef(startStep), trueStepRef(trueStep),
  molSetRef(set.mol), ffSetupRef(set.ff), pdbAtomsRef(set.pdb.atoms),
  startIdxMolecules(set.mol.molVars.startIdxMolecules)
{
  std::string file = set.config.in.files.checkpoint.name[0];
#if GOMC_LIB_MPI
  filename = sys.ms->replicaInputDirectoryPath + file;
#else
  filename = file;
#endif
}

CheckpointSetup::~CheckpointSetup(){}

std::string CheckpointSetup::getFileName(){
  return filename;
}

void CheckpointSetup::loadCheckpointFile(){
  // create and open a character archive for intput
  std::ifstream ifs(filename);
  if (!ifs.is_open()){
    fprintf(stderr, "Error opening checkpoint input file %s\n",
            filename.c_str());
    exit(EXIT_FAILURE);
  }
  cereal::BinaryInputArchive ia(ifs);
  ia >> chkObj;
  SetCheckpointData();
  std::cout << "Checkpoint loaded from " << filename << std::endl;
}

void CheckpointSetup::InitOver(){
  SetMolecules();
}

void CheckpointSetup::SetCheckpointData(){
  SetStepNumber();
  SetTrueStepNumber();
  SetMoveSettings();
  SetPRNGVariables();
  SetR123Variables();
  SetMolecules();
  SetMoleculeLookup();
  SetMoleculeSetup();
  SetPDBSetupAtoms();
}

#if GOMC_LIB_MPI
void CheckpointSetup::SetCheckpointData   (bool & parallelTemperingIsEnabled,
                                          PRNG & prngPT){
  SetStepNumber();
  SetTrueStepNumber();
  SetMoveSettings();
  SetPRNGVariables();
  SetR123Variables();
  SetMolecules();
  SetMoleculeLookup();
  SetMoleculeSetup();
  SetPDBSetupAtoms();
  SetParallelTemperingWasEnabled();
  if(parallelTemperingIsEnabled && parallelTemperingWasEnabled)
    SetPRNGVariablesPT();
}
#endif

void CheckpointSetup::SetStepNumber()
{
  startStepRef = chkObj.stepNumber;
}

void CheckpointSetup::SetTrueStepNumber()
{
  printf("%-40s %-lu \n", "Info: Loading true step from checkpoint", chkObj.trueStepNumber);
  trueStepRef = chkObj.trueStepNumber;
}

void CheckpointSetup::SetMoveSettings()
{
  moveSetRef.scale = chkObj.scaleVec;
  moveSetRef.acceptPercent = chkObj.acceptPercentVec;
  moveSetRef.accepted = chkObj.acceptedVec;
  moveSetRef.tries = chkObj.triesVec;
  moveSetRef.tempAccepted = chkObj.tempAcceptedVec;
  moveSetRef.tempTries = chkObj.tempTriesVec;
  moveSetRef.mp_tries = chkObj.mp_triesVec;
  moveSetRef.mp_accepted = chkObj.mp_acceptedVec;
  moveSetRef.mp_interval_accepted = chkObj.mp_interval_acceptedVec;
  moveSetRef.mp_interval_tries = chkObj.mp_interval_triesVec;
  moveSetRef.mp_t_max = chkObj.mp_t_maxVec;
  moveSetRef.mp_r_max = chkObj.mp_r_maxVec;
  for (int b = 0; b < BOXES_WITH_U_NB; ++b)
    moveSetRef.isSingleMoveAccepted[b] = chkObj.isSingleMoveAccepted[b];
}

void CheckpointSetup::SetPRNGVariables()
{
  prngRef.GetGenerator()->load(chkObj.saveArray);
  prngRef.GetGenerator()->pNext = prngRef.GetGenerator()->state + chkObj.seedLocation;
  prngRef.GetGenerator()->left = chkObj.seedLeft;
  prngRef.GetGenerator()->seedValue = chkObj.seedValue;
}

void CheckpointSetup::SetR123Variables()
{
  r123Ref.SetRandomSeed(chkObj.seedValue);
}

void CheckpointSetup::SetMolecules()
{
  molRef.restartOrderedStart = new uint [chkObj.originalMolSetup.molVars.moleculeIteration + 1];
  /* If new run, originalStart & originalKIndex and start & kIndex are identical */
  molRef.restartOrderedStart = vect::TransferInto<uint>(molRef.restartOrderedStart, chkObj.restartedStartVec);
}

void CheckpointSetup::SetMoleculeLookup(){
  /* Original Mol Indices are for constant trajectory output from start to finish of a single run*/
  molLookupRef = chkObj.originalMoleculeLookup;
}

void CheckpointSetup::SetMoleculeSetup(){
  molSetRef = chkObj.originalMolSetup;
  molSetRef.AssignKinds(molSetRef.molVars, ffSetupRef);
}

void CheckpointSetup::SetPDBSetupAtoms(){
  uint p, d, trajectoryI, dataI, placementStart, placementEnd, dataStart, dataEnd;
  for (int mol = 0; mol < chkObj.originalMolSetup.molVars.moleculeIteration; mol++){
    trajectoryI = chkObj.originalMoleculeLookup.restartMoleculeIndices[mol];
    dataI = mol;
    //Loop through particles in mol.
    GetOriginalRangeStartStop(placementStart, placementEnd, trajectoryI);
    GetRestartRangeStartStop(dataStart, dataEnd, dataI);
    for (p = placementStart, d = dataStart; p < placementEnd; ++p, ++d) {
      chkObj.originalAtoms.x[p] = pdbAtomsRef.x[d];
      chkObj.originalAtoms.y[p] = pdbAtomsRef.y[d];
      chkObj.originalAtoms.z[p] = pdbAtomsRef.z[d];
      chkObj.originalAtoms.beta[p] = pdbAtomsRef.beta[d];
      chkObj.originalAtoms.box[p] = pdbAtomsRef.box[d];
    }
  }
  // Should do a default assignment of the vectors and primitives.
  pdbAtomsRef = chkObj.originalAtoms;
}

void CheckpointSetup::SetMoleculeSetup(){
  molSetRef = chkObj.originalMolSetup;
  molSetRef.AssignKinds(molSetRef.molVars, ffSetupRef);
}

void CheckpointSetup::SetPDBSetupAtoms(){
  //pdbAtomsRef
}

#if GOMC_LIB_MPI
bool CheckpointSetup::SetParallelTemperingWasEnabled()
{
  parallelTemperingWasEnabled = (bool)chkObj.parallelTemperingEnabled;
}

void CheckpointSetup::SetPRNGVariablesPT(PRNG & prng)
{
  prngPT.GetGenerator()->load(chkObj.saveArrayPT);
  prngPT.GetGenerator()->pNext = prngPT.GetGenerator()->state + chkObj.seedLocationPT;
  prngPT.GetGenerator()->left = chkObj.seedLeftPT;
  prngPT.GetGenerator()->seedValue = chkObj.seedValuePT;
}
#endif

void CheckpointSetup::GetRestartRangeStartStop(uint & _start, uint & stop, const uint m) const
{
  _start = chkObj.restartedStartVec[m];
  stop = chkObj.restartedStartVec[m + 1];
}

void CheckpointSetup::GetOriginalRangeStartStop(uint & _start, uint & stop, const uint m) const
{
  _start = chkObj.originalStartVec[m];
  stop = chkObj.originalStartVec[m + 1];
}<commit_msg>I have to generate the startIdxMolecules for the next round since I dont parse the psf on restChk<commit_after>/*******************************************************************************
GPU OPTIMIZED MONTE CARLO (GOMC) 2.70
Copyright (C) 2018  GOMC Group
A copy of the GNU General Public License can be found in the COPYRIGHT.txt
along with this program, also can be found at <http://www.gnu.org/licenses/>.
********************************************************************************/

#include <stdint.h>
#include "CheckpointSetup.h"

CheckpointSetup::CheckpointSetup(ulong & startStep,
                                ulong & trueStep,
                                MoleculeLookup & molLookup,
                                MoveSettings & moveSettings,
                                Molecules & mol,
                                PRNG & prng,
                                Random123Wrapper & r123,
                                Setup & set) :
  molLookupRef(molLookup), moveSetRef(moveSettings), molRef(mol), prngRef(prng),
  r123Ref(r123), startStepRef(startStep), trueStepRef(trueStep),
  molSetRef(set.mol), ffSetupRef(set.ff), pdbAtomsRef(set.pdb.atoms),
  startIdxMolecules(set.mol.molVars.startIdxMolecules)
{
  std::string file = set.config.in.files.checkpoint.name[0];
#if GOMC_LIB_MPI
  filename = sys.ms->replicaInputDirectoryPath + file;
#else
  filename = file;
#endif
}

CheckpointSetup::~CheckpointSetup(){}

std::string CheckpointSetup::getFileName(){
  return filename;
}

void CheckpointSetup::loadCheckpointFile(){
  // create and open a character archive for intput
  std::ifstream ifs(filename);
  if (!ifs.is_open()){
    fprintf(stderr, "Error opening checkpoint input file %s\n",
            filename.c_str());
    exit(EXIT_FAILURE);
  }
  cereal::BinaryInputArchive ia(ifs);
  ia >> chkObj;
  SetCheckpointData();
  std::cout << "Checkpoint loaded from " << filename << std::endl;
}

void CheckpointSetup::InitOver(){
  SetMolecules();
}

void CheckpointSetup::SetCheckpointData(){
  SetStepNumber();
  SetTrueStepNumber();
  SetMoveSettings();
  SetPRNGVariables();
  SetR123Variables();
  SetMolecules();
  SetMoleculeLookup();
  SetMoleculeSetup();
  SetPDBSetupAtoms();
}

#if GOMC_LIB_MPI
void CheckpointSetup::SetCheckpointData   (bool & parallelTemperingIsEnabled,
                                          PRNG & prngPT){
  SetStepNumber();
  SetTrueStepNumber();
  SetMoveSettings();
  SetPRNGVariables();
  SetR123Variables();
  SetMolecules();
  SetMoleculeLookup();
  SetMoleculeSetup();
  SetPDBSetupAtoms();
  SetParallelTemperingWasEnabled();
  if(parallelTemperingIsEnabled && parallelTemperingWasEnabled)
    SetPRNGVariablesPT();
}
#endif

void CheckpointSetup::SetStepNumber()
{
  startStepRef = chkObj.stepNumber;
}

void CheckpointSetup::SetTrueStepNumber()
{
  printf("%-40s %-lu \n", "Info: Loading true step from checkpoint", chkObj.trueStepNumber);
  trueStepRef = chkObj.trueStepNumber;
}

void CheckpointSetup::SetMoveSettings()
{
  moveSetRef.scale = chkObj.scaleVec;
  moveSetRef.acceptPercent = chkObj.acceptPercentVec;
  moveSetRef.accepted = chkObj.acceptedVec;
  moveSetRef.tries = chkObj.triesVec;
  moveSetRef.tempAccepted = chkObj.tempAcceptedVec;
  moveSetRef.tempTries = chkObj.tempTriesVec;
  moveSetRef.mp_tries = chkObj.mp_triesVec;
  moveSetRef.mp_accepted = chkObj.mp_acceptedVec;
  moveSetRef.mp_interval_accepted = chkObj.mp_interval_acceptedVec;
  moveSetRef.mp_interval_tries = chkObj.mp_interval_triesVec;
  moveSetRef.mp_t_max = chkObj.mp_t_maxVec;
  moveSetRef.mp_r_max = chkObj.mp_r_maxVec;
  for (int b = 0; b < BOXES_WITH_U_NB; ++b)
    moveSetRef.isSingleMoveAccepted[b] = chkObj.isSingleMoveAccepted[b];
}

void CheckpointSetup::SetPRNGVariables()
{
  prngRef.GetGenerator()->load(chkObj.saveArray);
  prngRef.GetGenerator()->pNext = prngRef.GetGenerator()->state + chkObj.seedLocation;
  prngRef.GetGenerator()->left = chkObj.seedLeft;
  prngRef.GetGenerator()->seedValue = chkObj.seedValue;
}

void CheckpointSetup::SetR123Variables()
{
  r123Ref.SetRandomSeed(chkObj.seedValue);
}

void CheckpointSetup::SetMolecules()
{
  molRef.restartOrderedStart = new uint [chkObj.originalMolSetup.molVars.moleculeIteration + 1];
  /* If new run, originalStart & originalKIndex and start & kIndex are identical */
  molRef.restartOrderedStart = vect::TransferInto<uint>(molRef.restartOrderedStart, chkObj.restartedStartVec);
}

void CheckpointSetup::SetMoleculeLookup(){
  /* Original Mol Indices are for constant trajectory output from start to finish of a single run*/
  molLookupRef = chkObj.originalMoleculeLookup;
}

void CheckpointSetup::SetMoleculeSetup(){
  molSetRef = chkObj.originalMolSetup;
  molSetRef.AssignKinds(molSetRef.molVars, ffSetupRef);
}

void CheckpointSetup::SetPDBSetupAtoms(){
  uint p, d, trajectoryI, dataI, placementStart, placementEnd, dataStart, dataEnd;
  for (int mol = 0; mol < chkObj.originalMolSetup.molVars.moleculeIteration; mol++){
    trajectoryI = chkObj.originalMoleculeLookup.restartMoleculeIndices[mol];
    dataI = mol;
    //Loop through particles in mol.
    GetOriginalRangeStartStop(placementStart, placementEnd, trajectoryI);
    GetRestartRangeStartStop(dataStart, dataEnd, dataI);
    for (p = placementStart, d = dataStart; p < placementEnd; ++p, ++d) {
      chkObj.originalAtoms.x[p] = pdbAtomsRef.x[d];
      chkObj.originalAtoms.y[p] = pdbAtomsRef.y[d];
      chkObj.originalAtoms.z[p] = pdbAtomsRef.z[d];
      chkObj.originalAtoms.beta[p] = pdbAtomsRef.beta[d];
      chkObj.originalAtoms.box[p] = pdbAtomsRef.box[d];
    }
  }
  // Should do a default assignment of the vectors and primitives.
  pdbAtomsRef = chkObj.originalAtoms;
}

void CheckpointSetup::SetMoleculeSetup(){
  molSetRef = chkObj.originalMolSetup;
  molSetRef.AssignKinds(molSetRef.molVars, ffSetupRef);
}

void CheckpointSetup::SetPDBSetupAtoms(){
  uint p, d, trajectoryI, dataI, placementStart, placementEnd, dataStart, dataEnd;
  for (int mol = 0; mol < chkObj.originalMolSetup.molVars.moleculeIteration; mol++){
    trajectoryI = molLookupRef.originalMoleculeIndices[mol];
    dataI = mol;
    //Loop through particles in mol.
    GetOriginalRangeStartStop(placementStart, placementEnd, trajectoryI);
    GetRangeStartStop(dataStart, dataEnd, dataI);
    for (p = placementStart, d = dataStart; p < placementEnd; ++p, ++d) {
      chkObj.originalAtoms.x[p] = pdbAtomsRef.x[d];
      chkObj.originalAtoms.y[p] = pdbAtomsRef.y[d];
      chkObj.originalAtoms.z[p] = pdbAtomsRef.z[d];
      chkObj.originalAtoms.beta[p] = pdbAtomsRef.beta[d];
      chkObj.originalAtoms.box[p] = pdbAtomsRef.box[d];
    }
  }
}

#if GOMC_LIB_MPI
bool CheckpointSetup::SetParallelTemperingWasEnabled()
{
  parallelTemperingWasEnabled = (bool)chkObj.parallelTemperingEnabled;
}

void CheckpointSetup::SetPRNGVariablesPT(PRNG & prng)
{
  prngPT.GetGenerator()->load(chkObj.saveArrayPT);
  prngPT.GetGenerator()->pNext = prngPT.GetGenerator()->state + chkObj.seedLocationPT;
  prngPT.GetGenerator()->left = chkObj.seedLeftPT;
  prngPT.GetGenerator()->seedValue = chkObj.seedValuePT;
}
#endif

void CheckpointSetup::GetRestartRangeStartStop(uint & _start, uint & stop, const uint m) const
{
  _start = chkObj.restartedStartVec[m];
  stop = chkObj.restartedStartVec[m + 1];
}

void CheckpointSetup::GetOriginalRangeStartStop(uint & _start, uint & stop, const uint m) const
{
  _start = chkObj.originalStartVec[m];
  stop = chkObj.originalStartVec[m + 1];
}<|endoftext|>