Всех Украинцев с новым годом!

Хочу поздравить все украинское хабрасообщество с наступающим новым годом и также новым годом, для тех кто увидит топик позже!!!
Особенное спасибо хочу сказать Дмитрию Савчеко за организацию хабравстреч(кому надо, найдет сам)
Хочу пожелать всем нам поменьше бед и побольше удач в новом году!
ОТМЕЧАЕМ!!!

ссылка на оригинал статьи http://habrahabr.ru/post/164505/

Множественные Assertion’ы без прерываний в одном юнит-тесте на примере NUnit

В практике юнит-тестирования часто возникает желание сделать несколько Assertion’ов в одном тест-методе. В теории же, такой подход критикуется с двух основных позиций. Во-первых, семантически, один тест должен проверять только один кейс, не разрастаться. Во-вторых, при падении одного из Assertion’ов в цепочке, выполнение теста прервется и мы увидим сообщение об ошибке лишь от него, а до всех остальных дело не дойдет, что не даст наиболее полной картины произошедшего. Первый аргумент безусловно резонен и при написании тестов его всегда следует держать в голове, но фанатичное следование этому принципу зачастую не представляется разумным (пример далее). Устранению же второй проблемы посвящен этот пост. Будет представлен небольшой класс, позволяющий просто и лаконично обеспечить исполнение нескольких Assertion’ов без прерывания выполнения метода и с выводом сообщения об ошибке каждого из них.

Итак, предположим, у нас есть класс Size, который, помимо прочего, принимает параметром конструктора значение в дюймах, а в себе содержит аксессоры для получения количества целых футов и оставшихся дюймов, т.е., передав на вход 16, мы получим 1 фут и 4 дюйма (в одном футе 12 дюймов).

public class Size {     public int Feet { get; private set; }     public int RemainderInches { get; private set; }      public Size(int totalInches)     {         // код конструктора     }      //... } 

Чтобы не растекаться тестами конструктора по древу и вместе с тем обеспечить годное покрытие хочется написать что-то вроде:

[Test] public void ConstructorSuccess() {     var zeroSize = new Size(0);     var inchesOnlySize = new Size(2);     var mixedSize = new Size(15);     var feetOnlySize = new Size(36);      Assert.That(zeroSize.Feet == 0 && zeroSize.RemainderInches == 0, "Zero size");     Assert.That(inchesOnlySize.Feet == 0 && inchesOnlySize.RemainderInches == 2, "Inches-only size");     Assert.That(mixedSize.Feet == 1 && mixedSize.RemainderInches == 3, "Inches and feet size");     Assert.That(feetOnlySize.Feet == 3 && feetOnlySize.RemainderInches == 0, "Feet-only size"); } 

Disclaimer: Вместо одной проверки на истинность можно (и даже хорошо бы) использовать по две проверки на равенство, но в данном коротком примере это не принципиально, а код бы усложнило.

Ясно, что если выделять по методу на каждый такой Assertion, то наш тест-класс очень быстро обрастет огромным числом методов и в реальности, в результате, будем иметь сотни тестов, но толку не больше. Однако, в показанном подходе, как уже было сказано, при падении одного из Assertion’ов данных от остальных мы не увидим, т.к. выполнение метода остановится.

Приступим к устранению этого неудобства.

В NUnit падение теста происходит при возникновении любого непойманного Exception’a, а сам класс Assert при неудаче бросает AssertionException с полными сообщениями об ошибках. Таким образом, по сути, нам нужно обеспечить отлов исключений на протяжении тест-метода, накапливание их сообщений и вывод накопленного в конце. Естественно, что заниматься этим явно, прямо в коде самого теста — страшный ужас.

После некоторых размышлений, для этих целей был предложен класс-аккумулятор, использование которого внутри тест-метода из примера выше выглядит следующим образом:

var assertsAccumulator = new AssertsAccumulator();  assertsAccumulator.Accumulate(     () => Assert.That(zeroSize.Feet == 0 && zeroSize.RemainderInches == 0, "Zero size")); assertsAccumulator.Accumulate(     () => Assert.That(inchesOnlySize.Feet == 0 && inchesOnlySize.RemainderInches == 2, "Inches-only size")); assertsAccumulator.Accumulate(     () => Assert.That(mixedSize.Feet == 1 && mixedSize.RemainderInches == 3, "Inches and feet size")); assertsAccumulator.Accumulate(     () => Assert.That(feetOnlySize.Feet == 3 && feetOnlySize.RemainderInches == 0, "Feet-only size"));  assertsAccumulator.Release(); 

Другой пример использования (надеюсь, код говорит сам за себя и понятен без комментариев):

Result<User> signInResult = authService.SignIn(TestUsername, TestPassword);  var assertsAccumulator = new AssertsAccumulator(); assertsAccumulator.Accumulate(() => Assert.That(signInResult.IsSuccess)); assertsAccumulator.Accumulate(() => Assert.That(signInResult.Value, Is.Not.Null)); assertsAccumulator.Accumulate(() => Assert.That(signInResult.Value.Username, Is.EqualTo(TestUsername))); assertsAccumulator.Accumulate(() => Assert.That(signInResult.Value.Password, Is.EqualTo(HashedTestPassword))); assertsAccumulator.Release(); 

Результат выполнения этого примера с выводом двух ошибок одновременно показан на завлекающем скрине в начале поста.

Реализация AssertsAccumulator’a выглядит так:

public class AssertsAccumulator {     private StringBuilder Errors { get; set; }     private bool AssertsPassed { get; set; }      private String AccumulatedErrorMessage     {         get         {             return Errors.ToString();         }     }      public AssertsAccumulator()     {         Errors = new StringBuilder();         AssertsPassed = true;     }      private void RegisterError(string exceptionMessage)     {         AssertsPassed = false;         Errors.AppendLine(exceptionMessage);     }      public void Accumulate(Action assert)     {         try         {             assert.Invoke();         }         catch (Exception exception)         {             RegisterError(exception.Message);         }     }      public void Release()     {         if (!AssertsPassed)         {             throw new AssertionException(AccumulatedErrorMessage);         }     } } 

Как видно, наружу выставлены лишь два метода, Accumulate() и Release(), использование которых довольно прозрачно. Прием делегата методом Accumulate делает класс очень универсальным, можно передавать любые виды Assertion’ов (как и показано в примере с signInResult) и при необходимости класс можно очень легко адаптировать под любой другой тестовый фреймворк сменив только тип бросаемого Exception’a внутри Release().

Из примеров видно, что класс позволяет удобным образом писать тест-методы, содержащие в себе несколько Assertion’ов, при этом выполняющиеся всегда до конца и имеющие полный вывод информации об ошибках.

В заключение хочется напомнить, что фанатичное следование какому-либо принципу редко является чем-то хорошим, и чрезмерно использование такого класса — не исключение. Нужно понимать, что использовать его можно только тогда, когда несколько Assertion’ов действительно проверяют одну семантическую изолированную операцию или сценарий и размещение их в одном тесте оправдано.

ссылка на оригинал статьи http://habrahabr.ru/post/164479/

Новогодний IT-шар

Всех с Новым Годом!

Я являюсь автором iPixelSDK и тоже присоединяюсь к новогодней демосцене.

Видео и больше про процесс создания шара под катом.

Устройство: iPad
Движок: Cocos2d 2.0
Среда разработки: iPad iPixelSDK 1.0

Процесс разработки на iPad выглядит следующим образом:

Шар состоит из 4х функций и 2х шейдеров.

201000: 20. Stars (radial) Функция управления шара. Инициализирует объект, вызывает функцию перемещения, подключает функцию отрисовки и шейдеры.

201010: 20.0.#draw (radial) Функция отрисовки. Рисует vertex array.

201020: 20.0.#init_stars (radial) Инициализация шара, задает количество точек, цвет и позицию каждой точки в сферической системе координат.

201030: 20.0.#move_stars (radial) Перемещение точек, вращение по осям xz, xy.

201100:S: 20.0.^starfield.vsh (radial) Вертексный шейдер, устанавливает размер точек, переводит сферические координаты в трехмерные декартовы, после чего в двухмерные (поскольку cocos2d 2d-движок).

201101:S: 20.0.^starfield.fsh (radial) Пиксельный шейдер, рисует блик.

Спасибо за внимание. Жду ваших комментариев.

ссылка на оригинал статьи http://habrahabr.ru/post/164501/

Моделирование электрического поля средствами CUDA

Данная статья написана с целью продемонстрировать как с помощью технологии CUDA можно смоделировать простое взаимодействие заряженых частиц (см. Закон Кулона). Для вывода статической картинки я использовал библиотеку freeglut.
Как пишут частенько на Хабре:

Ещё во времена Turbo Pascal и Borland C 5.02 меня интересовал процесс симуляции простых физических явлений природы — будь то силы гравитационного притяжения или кулоновского взаимодействия. К сожалению, мощности одного процессора с несколькими сотнями МГц не хватало для простых математических операций, коих множество было велико.

Хоть я и не погроммист, мне захотелось однажды вспомнить далёкое детство, да и подучить основы JavaScript, и я как-то смоделировал гравитационное взаимодействие любого разумного числа материальных точек. Так, например, частичка ниже крутится вокруг «солнца» пользуясь Ньютоновским законом:

Если вам будет интересно, и меня не оставит энтузиазм, то я опишу вам создание такой вот демки, чтобы вы смогли написать своих злых птиц в вакууме.

Итак, хватит ностальгировать, давайте погромпрограммировать. Моя платформа — это ноутбук с Ubuntu и видеокартой GeForce GT 540m и установленным CUDA Toolkit 5.0. Если вы начинаете знакомство с CUDA, то могу вам посоветовать интересную книгу CUDA by Example.

Для начала создайте проект из шаблона Nsight и подключите к нему freeglut используя библиотеки GLU, GL, glut. Это позволит нам отобразить полученное векторное поле, которое мы рассчитаем. Приблизительная структура нашего файла с функцией main будет следующая:

#include <stdio.h> #include <stdlib.h>  int main(int argc, char** argv) { 	// Initialize freeglut 	// ... 	 	// Initialize Host and Device variables 	// ... 	 	// Launch Kernel to render the image 	 	// Display Image 	 	// Free resources 	 	return 0; } 

Для начала, всё выглядит просто. Давайте, сперва, отобразим окно нужного нам размера ну и срендерим чёрный экран. Кстати, скажу вам очевидную вещь: если какая-то функция вам незнакома, то просто погуглите.

Инициализация окна

Так как я, когда задумывал приложение, не планировал динамическое изменение размера окна, то я решил указать его декларативно, используя глобальные константы:

const int width = 1280; const int height = 720; 

Ах да! Не судите строго за смешивание стилей C++ и C99. Некоторые вещи, типа перегрузки, я порой нахожу полезным, но и от malloc я не отказался, чтобы хоть как-нибудь следовать стилю приложениям с CUDA.

Само отображение окна, обработка клавиши Escape и простой рендер можно осуществить следующим кодом:

#include <GL/freeglut.h> #include <GL/gl.h> #include <GL/glext.h>  // ...  void key(unsigned char key, int x, int y) { 	switch (key) { 	case 27: 		printf("Exit application\n"); 		glutLeaveMainLoop(); 		break; 	} }  void draw(void) { 	glClearColor(0.0, 0.0, 0.0, 1.0); 	glClear(GL_COLOR_BUFFER_BIT); 	// glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_BYTE, screen); 	glFlush(); }  // ... 	// Initialize freeglut 	glutInit(&argc, argv); 	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); 	glutInitWindowSize(width, height); 	glutCreateWindow("Electric field"); 	glutDisplayFunc(draw); 	glutKeyboardFunc(key); 	glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);  	// ...  	// Display Image 	glutMainLoop(); 

При запуске этого кода, вы ничего кроме чёрного экрана не увидите. Так что я опущу здесь скриншот. Обратите внимание на следующие моменты:

  • glutLeaveMainLoop — когда нажат Escape, то freeglut позволяет прервать главный цикл, чтобы мы смогли освободить ресурсы приложения. Если хочется, то можно использовать и atexit;
  • glDrawPixels — позже я создам буфер из unsigned byte, где я буду хранить все пиксели (их цвета) и потом отображать в окне;
  • glutSetOption — это мне позволить продолжить выполнение кода в main, чтобы очистить ресурсы в виде динамической памяти.

Разбиение вычисление на блоки и потоки

Побаловавшись с примерами, я смог для себя уяснить, что представляет собой такое понятие как блок и поток, и что делать с их размерностью. В принципе, если опустить технические детали, то блок — это клетка, в которой есть некоторое количество потоков. Когда происходит вычисление целой сетки блоков, то в какой-то момент времени каждый блок выстреливает свои потоки, дожидается их завершения и передает управление другому блоку. Так, например, вы можете нагенерить блоки в одномерную полоску, или в двухмерную сетку.

Потоки, в свою очередь, тоже могут располагаться в блоке в виде одномерной полосы, или двухмерной таблицы. Кстати, возможны варианты с тремя измерениями, но я их упущу, так как они пока не вписываются в мою задачу.

Я могу разбить экран на большие квадраты (блоки), внутри которых пиксели будут рендериться отдельным потоком. Такая задача — оптимальное использование графической карты, но чтобы разбить экран на блоки, придется применить простую арифметику — я узнаю число потоков дозволенного мне в пределах блока, и затем поделю размер окна на количество потоков по горизонтали и вертикали.

Чтобы узнать количество потоков внутри блока, воспользуемся функцией cudaGetDeviceProperties:

int threadsCount(void) { 	int deviceCount = 0; 	cudaGetDeviceCount(&deviceCount);  	if (deviceCount <= 0) { 		printf("No CUDA devices\n"); 		exit(-1); 	}  	cudaDeviceProp properties; 	cudaGetDeviceProperties(&properties, 0);  	return properties.maxThreadsPerBlock; } 

Моя карта возвращает число 1024. К сожалению, я не могу использовать все потоки, потому что в режиме отладки, при делении float чисел, я получаю ошибку cudaErrorLaunchOutOfResources. Я так и не смог отыскать, почему мне не хватило ресурсов (или регистров, как пишет интернет), поэтому единственные три решения, что я смог найти — это снижение числа потоков на блок, использование release режима при компиляции, использование опции maxrregcount с любым числом больше нуля.
Если вы дочитали мою статью до этого момента, то я рад, что не зря сижу ночью перед компом. А если вы знаете ответ, как узнать в чем именно была моя ошибка, и сообщите мне его, то я буду рад вдвойне.

Теперь разобьём наше поле на блоки и потоки:

void setupGrid(dim3* blocks, dim3* threads, int maxThreads) { 	threads->x = 32; 	threads->y = maxThreads / threads->x - 2; // to avoid cudaErrorLaunchOutOfResources error  	blocks->x = (width + threads->x - 1) / threads->x; 	blocks->y = (height + threads->y - 1) / threads->y; }  // ... 	// Initialize Host 	dim3 blocks, threads; 	setupGrid(&blocks, &threads, threadsCount()); 	printf("Debug: blocks(%d, %d), threads(%d, %d)\nCalculated Resolution: %d x %d\n", 		blocks.x, blocks.y, threads.x, threads.y, blocks.x * threads.x, 		blocks.y * threads.y); 

Результат будет следующим (я заведомо увеличил количество блоков на единицу в тех случаях, когда размер экрана не кратен числу потоков):

Debug: blocks(40, 24), threads(32, 30) Calculated Resolution: 1280 x 720 

Теория и практика

Заряды, расстояния, кулоны и коэффициенты — это звучит хорошо. Но когда дело доходит до моделирования, то тут мы не можем уже пользоваться супер-маленькими значениями, потому что они могут пропасть в процессе вычисления. Поэтому мы упростим задачу:

Заряд — это структура с координатами (как на экране).

struct charge { 	int x, y, q; }; 

Напряжённость электрического поля в точке — это вектор, который мы выразим проекциями и функции, вычисляющей их (вот именно здесь я и получил свою ошибку):

const float k = 50.0f; const float minDistance = 0.9f; // not to divide by zero const float maxForce = 1e7f;  struct force { 	float fx, fy;  	__device__ force() : 			fx(0.0f), fy(0.0f) { 	}  	__device__ force(int fx, int fy) : 			fx(fx), fy(fy) { 	}  	__device__ float length2() const { 		return (fx * fx + fy * fy); 	}  	__device__ float length() const { 		return sqrtf(length2()); 	}  	__device__ void calculate(const charge& q, int probe_x, int probe_y) { 		// F(1->2) = k * q1 * q2 / r(1->2)^2 * vec_r(1->2) / abs(vec_r(1->2)) 		// e = vec_F / q2 		fx = probe_x - q.x; 		fy = probe_y - q.y;  		float l = length(); 		if (l <= minDistance) { 			return; 		}  		float e = k * q.q / (l * l * l); 		if (e > maxForce) { 			fx = fy = maxForce; 		} else { 			fx *= e; 			fy *= e; 		} 	}  	__device__ force operator +(const force& f) const { 		return force(fx + f.fx, fy + f.fy); 	}  	__device__ force operator -(const force& f) const { 		return force(fx - f.fx, fy - f.fy); 	}  	__device__ force& operator +=(const force& f) { 		fx += f.fx; 		fy += f.fy; 		return *this; 	}  	__device__ force& operator -=(const force& f) { 		fx -= f.fx; 		fy -= f.fy; 		return *this; 	} }; 

Задумка моя простая — я создам двухмерный массив из векторов напряжённостей. В каждой точке экрана, напряжённость будет равна сумме векторов кулоновских сил. Звучит заумно, но я иначе не смог сформулировать. Проще сказать, код будет вот таким (вы его прочтите, но не пишите ещё в свой проект):

	force temp_f; 	for (int i = 0; i < chargeCount; i++) { 		temp_f.calculate(charges[i], x, y); 		*f += temp_f; 	} 

Если мы попадём в заряд, то я пропускаю вычисление напряженности в этой точке (ибо делить на ноль нельзя). Так что на экране вы должны увидеть чёрную точку — заряд.

Теперь, когда мы создали инфраструктуру — давайте кодить под CUDA. Для начала создадим необходимые переменные хоста и устройства и освободим их!

Создаем и освобождаем ресурсы

Нам понадобятся следующие переменные:

  • экран — хост — цветные пиксели;
  • экран — устройство — они же;
  • заряды — устройство — координаты и величины зарядов в постоянной памяти устройства.

Создаём:

uchar4* screen = NULL;  // ...  	screen = (uchar4*) malloc(width * height * sizeof(uchar4)); 	memset(screen, 0, width * height * sizeof(uchar4));  	uchar4 *dev_screen = NULL; 	cudaMalloc((void**) &dev_screen, width * height * sizeof(uchar4)); 	cudaMemset(dev_screen, 0, width * height * sizeof(uchar4));  // ...  	// Free resources 	free(screen); 	screen = NULL;  	cudaFree(dev_screen); 	dev_screen = NULL; 

Заряды проинициализируем просто. Я не сбрасываю генератор случайных чисел, чтобы получить одну и ту же картину. Если вы хотите случайное поле каждый раз, то можете добавить вызов srand:

const int chargeCount = 10; __constant__ charge dev_charges[chargeCount]; const int maxCharge = 1000; const int minCharge = -1000;  // ...  void prepareCharges(void) { 	charge* charges = (charge*) malloc(chargeCount * sizeof(charge)); 	for (int i = 0; i < chargeCount; i++) { 		charges[i].x = rand() % width; 		charges[i].y = rand() % height; 		charges[i].q = rand() % (maxCharge - minCharge) + minCharge;  		printf("Debug: Charge #%d (%d, %d, %d)\n", i, charges[i].x, 				charges[i].y, charges[i].q); 	} 	cudaMemcpyToSymbol(dev_charges, charges, chargeCount * sizeof(charge)); }  // ... 	prepareCharges(); 

Помните закомментированную строку, рендерящую экран? Теперь вы можете её раскомментировать:

	glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_BYTE, screen); 

Создадим ядро

Теперь создадим функцию, которую мы будем вызыватhttp://habrahabr.ru/sandbox/add/#ь в каждом потоке, чтобы срендерить каждый пиксель на экране. Эта функция будет выполнять следующее: она вычислит значение напряжённости поля, и вызовет другую функцию, чтобы сопоставить какой-нибудь цвет точке.

__device__ uchar4 getColor(const force& f) { 	uchar4 color; 	color.x = color.y = color.z = color.w = 0;  	float l = f.length(); 	color.x = (l > maxLengthForColor ? 255 : l * 256 / maxLengthForColor);  	return color; }  __global__ void renderFrame(uchar4* screen) { 	// build the field and render the frame } 

Чтобы вызвать ядро… а впрочем и так всё ясно:

	// Launch Kernel to render the image 	renderFrame<<<blocks, threads>>>(dev_screen);  	cudaMemcpy(screen, dev_screen, width * height * sizeof(uchar4), 			cudaMemcpyDeviceToHost); 

Теперь добавим немного кода в renderFrame и получим то, что нам нужно:

__global__ void renderFrame(uchar4* screen) { 	int x = blockIdx.x * blockDim.x + threadIdx.x; 	int y = blockIdx.y * blockDim.y + threadIdx.y;  	force f, temp_f; 	for (int i = 0; i < chargeCount; i++) { 		temp_f.calculate(dev_charges[i], x, y); 		f += temp_f; 	}  	screen[x + y * width] = getColor(f); } 

Вывод

Часто народ пропускает статью, потому что важен вывод. Мне здесь нечего сказать, кроме как опубликовать картинку, что у меня получилась. Ссылку на почти пустой репозиторий найдёте здесь.

В принципе, есть куда развиваться — можно например добавить анимацию, показывающую как меняется поле при перемещении зарядов. Но опять же, если это интересно.

ссылка на оригинал статьи http://habrahabr.ru/post/164499/