Пример #1
0
LifeGameMpiMaster::LifeGameMpiMaster(const field_t &field)
: field(field), width(field.size()), height(field[0].size()),
  running(false), maxVersion(0)
{
  MPI_Comm_size(MPI_COMM_WORLD, &nodesCount);
  int chunkSize = field.size() / (nodesCount - 1);
  if (chunkSize != 0) {
    bufSize = packSize(2 * chunkSize, height) + 1000;
  } else {
    bufSize = packSize(width, height) + 1000;
  }
  buf = (char*)malloc(bufSize);
  int curChunk = 0;
  for (size_t i = 1; i < nodesCount; ++i) {
    //(currentChunk, currentChunk + chunkSize)
    size_t messageLen;
    pack(field, curChunk - 1,
      1 + (i == nodesCount - 1 ? width : curChunk + chunkSize),
      buf, messageLen);
      DBG(curChunk - 1 << " " << 1 + (i == nodesCount - 1 ? width : curChunk + chunkSize));
      DBG("Sending field to " << i);
      DBG(toString(unpack(buf)));
    MPI_Send(buf, messageLen, MPI_CHAR, i, NEW_FIELD_TAG, MPI_COMM_WORLD);
    curChunk += chunkSize;
  }

}
Пример #2
0
void randomCommand(const unsigned int &numRows, const unsigned int &numCols) {
	initializeStructures();
	vector<bool> buf(numCols, false);
	field.resize(numRows, buf);
	field2.resize(numRows, buf);
	srand(time(0));
	for (int i = 0; i < numRows; ++i) {
		for (int j = 0; j < numCols; ++j) {
			bool value = rand() % 2;
			field[i][j] = value;
			field2[i][j] = value;
		}
	}
}
Пример #3
0
void check_field(const std::string& _path, const field_t& field, error_context_t& ctx)
{
    std::string path = _path + "." + field.name;
    check_name(path, field.name, ctx);
    if(field.width == 0)
        ctx.add(error_t(error_t::WARNING, path, "field has width 0"));
    soc_word_t max = field.bitmask() >> field.pos;
    std::set< std::string > names;
    std::map< soc_word_t, std::string > map;
    for(size_t i = 0; i < field.enum_.size(); i++)
    {
        soc_word_t v = field.enum_[i].value;
        std::string n = field.enum_[i].name;
        std::string path_ = path + "." + n;
        check_name(path_, n, ctx);
        if(v > max)
            ctx.add(error_t(error_t::FATAL, path_, "value does not fit into the field"));
        if(names.find(n) != names.end())
            ctx.add(error_t(error_t::FATAL, path, "duplicate name '" + n + "' in enums"));
        names.insert(n);
        if(map.find(v) != map.end())
            ctx.add(error_t(error_t::WARNING, path, "'" + n + "' and '" + map[v] + "' have the same value"));
        map[v] = n;
    }
}
Пример #4
0
WorkerThread::WorkerThread(int id, const field_t& allField, int from, int to,
  MasterThread& master)
:id(id), topSem(0), bottomSem(0),
 topRead(1), bottomRead(1), master(master),  stepCount(0) {
  //DBG("thread " << id << " got allField " << toString(allField));
  //DBG("thread " << id << " got from " << from << " to " << to);
  //DBG("thread " << id << " allField size " << allField.size());
  for (int i = from - 1; i < to + 1; ++i) {
    //DBG("i " << i);
    int normi = (i + allField.size()) % allField.size();
    //DBG("normi " << normi);
    //DBG("allField[normi] " << toString(allField[normi]));
    field.push_back(allField[normi]);
    //DBG("field " << toString(field));
  }
  //DBG("thread " << id << " initialized field " << toString(field));
}
Пример #5
0
MasterThread::MasterThread(const field_t& field, int threadCount)
:WorkerThread(-1, field, 0, 0, *this), threadCount(threadCount), maxStepCount(0) {
  workerThreads = new WorkerThread*[threadCount];
  int chunkSize = field.size() / threadCount;
  int currentChunk = 0;
  for (int i = 0; i < threadCount; ++i) {
    workerThreads[i] = new WorkerThread(i, field, currentChunk,
      (i == threadCount - 1) ? field.size() : currentChunk + chunkSize,
      *this);
    currentChunk += chunkSize;
  }
  for (int i = 0; i < threadCount; ++i) {
    workerThreads[i]->top = workerThreads[(i - 1 + threadCount) % threadCount];
    workerThreads[i]->bottom = workerThreads[(i + 1 + threadCount) % threadCount];
  }
  top = workerThreads[threadCount - 1];
  bottom = workerThreads[0];
  bottom->top = this;
  top->bottom = this;
  running = true;
}
Пример #6
0
int startCommand(const string &filePath) {
	initializeStructures();
	ifstream file;
	file.open(filePath);
	field.clear();
	field2.clear();
	while (!file.eof()) {
		vector<bool> buf;
		string str;
		getline(file, str);
		for (unsigned int i = 0; i < str.size(); ++i) {
			if (str[i] == '1') {
				buf.push_back(true);
			}
			if (str[i] == '0') {
				buf.push_back(false);
			}
		}
		field.push_back(buf);
		field2.push_back(buf);
	}
	file.close();
	return field.size();
}
Пример #7
0
void statusCommand() {
	int x = field.size();
	if (x < 1) {
		cout << "Error in taking number of rows\n";
		return;
	}
	cout << "Iteration #" << stoppedIteration << "\n";
	int y = field[0].size();
	for (int i = 0; i < x; ++i) {
		for (int j = 0; j < y; ++j) {
			if (whichTable == 0) {
				cout << field[i][j] << " ";
			} else {
				cout << field2[i][j] << " ";
			}
		}
		cout << "\n";
	}
}
Пример #8
0
LifeGame::LifeGame(const field_t& field, int threadCount)
: field(field), syncNeeded(false) {
  this->width = field.size();
  this->height = field[0].size();
  master = new MasterThread(field, threadCount);
}
Пример #9
0
void* runParallel(void* arg) {
	args_t* arg_str = (args_t*)arg;
	int numIterations = arg_str->numIterations;
	int id = arg_str->pid;
	int x = field.size();
	if (x < 1) {
		printf("Pid: %d - Error in taking number of rows\n", id);
		return NULL;
	}
	int y = field[0].size();
	int range = ceil((double)x / (double)NUM_WS);
	int upBorder = min(range * id, x), downBorder = min(range * (id + 1), x);
	int down = (id + NUM_WS + 1) % NUM_WS, up = (id + NUM_WS - 1) % NUM_WS;
	field_t *ptr1, *ptr2;
	if (whichTable == 0) {
		ptr1 = &field;
		ptr2 = &field2;
	} else {
		ptr1 = &field2;
		ptr2 = &field;
	}
	for (int it = 0; it < numIterations; ++it) {
		for (int i = upBorder; i < downBorder; ++i) {
			for (int j = 0; j < y; ++j) {
				int numNeighbors = 0;
				int upper = (i + x - 1) % x;
				int lower = (i + x + 1) % x;
				int left = (j + y - 1) % y;
				int right = (j + y + 1) % y;
				if ((*ptr1)[upper][j]) {
					numNeighbors++;
				}
				if ((*ptr1)[upper][left]) {
					numNeighbors++;
				}
				if ((*ptr1)[upper][right]) {
					numNeighbors++;
				}
				if ((*ptr1)[lower][j]) {
					numNeighbors++;
				}
				if ((*ptr1)[lower][left]) {
					numNeighbors++;
				}
				if ((*ptr1)[lower][right]) {
					numNeighbors++;
				}
				if ((*ptr1)[i][left]) {
					numNeighbors++;
				}
				if ((*ptr1)[i][right]) {
					numNeighbors++;
				}
				if (!(*ptr1)[i][j] && numNeighbors == 3) {
					(*ptr2)[i][j] = true;
				} else if ((*ptr1)[i][j] && (numNeighbors < 2 || numNeighbors > 3)) {
					(*ptr2)[i][j] = false;
				} else {
					(*ptr2)[i][j] = (*ptr1)[i][j];
				}
			}
		}
		swap(ptr1, ptr2);
		int lockStatus = sem_trywait(&iterationSem);
		if (lockStatus != 0) {
			if (gameFinished) {
				stoppedIteration += it;
				whichTable = (whichTable + it) % 2;
				printf("Stopped at iteration #%d\n", stoppedIteration);
				stopped = true;
			}
			pthread_mutex_lock(&mutexCV);
			sem_init(&iterationSem, 0, NUM_WS - 1);
			for (int i = 0; i < NUM_WS; ++i) {
				isReady[i] = true;
			}
			pthread_cond_broadcast(&iterationCV);		
			pthread_mutex_unlock(&mutexCV);
		}
		
		pthread_mutex_lock(&mutexCV);
		while (!isReady[id]) {
			pthread_cond_wait(&iterationCV, &mutexCV);
		}
		isReady[id] = false;
		pthread_mutex_unlock(&mutexCV);

		if (stopped && gameFinished) {
			return NULL;
		}
	}
	if (id == 0) {
		stoppedIteration += numIterations;
		whichTable = (whichTable + numIterations) % 2;
	}
	return NULL;
}