воскресенье, 21 ноября 2010 г.

Сцены OpenGL в виджетах GTK

Весь интернет пестрит примерами использования OpenGL. Найти их не сложно. OpenGL сам по себе является кроссплатформенным. А поэтому, чтобы создать сцену OpenGL вам нужно знать только сам OpenGL. А вот когда сама сцена создана, встает вопрос - и куда мы эту сцену будем "запихивать"? Вот тут-то и всплывает "однобокость" этого великого разнообразия примеров OpenGL: они демонстрируют создание упомянутых сцен в одном единственном окне, окне библиотеки GLUT. Эта библиотека, как я понял, и была создана всего-навсего для написания "образовательных" и демонстрационных целей. И эти цели она выполнила и даже перевыполнила. Также к ее плюсам можно добавить ее кроссплатформенность. Ее реализиция есть и для систем UNIX и для Windows. Но ведь сцены OpenGL не являются необходимыми "сами по себе". Понятно же, что приложение, которое представляет из себя одно единственное окно с ,пусть с даже очень впечатляющим и красивым, двух- или трех- мерным изображением, вряд ли представит из себя какой-либо интерес, кроме, как мы уже указали, демонстрационного.
Здесь мы рассмотрим как вставить сцену OpenGL в виджет GTK. Интерфейс любого приложения GTK является набором, комбинацией так-называемых виджетов, размещенных, как укажет программист, на окнах приложения. Четкого определения, что такое виджет нет, из-за того, что это очень общее, объемное, понятие. Причем его "общность" истинна, так как на самом деле понять, что такое виджет совсем просто. Сложнее рассказать. Виджет - это "нечто", что можно отобразить на эране, окне приложения, диалоге. Любая кнопка, элемент управления, некая область, которая четко отделена и распознаваема от остальной части дилога, окна и есть виджет. Виджет GTK- это просто некий тип, структура GtkWidget.
Вот мы и подобрались вплотную к основной теме. Рассмотрим два виджета, которые позволяют рисовать сцены OpenGL в себя. Эти виджеты: gtkglarea и gtkglext. Имеются их реализации в виде пакетов для. самых распространенных по-крайней мере, дистрибутивов Linux. Также есть их порты для FreeBSD, что заставляет меня предполагать, что они есть для всех систем BSD.
Рассмотрим сначала gtkglarea.
Создаем файл gtkglarea_demo.c следующего содержания (вообще-то это совсем немного измененный для собственных нужд файл взятый отсюда):


#include <GL/gl.h>
#include <GL/glu.h>
#include <gtk/gtk.h>
#include <gtkgl/gtkglarea.h>

gint glarea_button_press (GtkWidget*, GdkEventButton*);
gint glarea_draw (GtkWidget*, GdkEventExpose*);
gint glarea_reshape (GtkWidget*, GdkEventConfigure*);
gint glarea_init (GtkWidget*);
gint glarea_destroy (GtkWidget*);
int main (int, char**);

gint
glarea_button_press (GtkWidget* widget, GdkEventButton* event) {
int x = event->x;
int y = event->y;
if (event->button == 1) {
g_print ("Button 1 press (%d, %d)\n", x, y);
return TRUE;
}
if (event->button == 2) {
g_print ("Button 1 press (%d, %d)\n", x, y);
return TRUE;
}
return FALSE;
}

gint
glarea_draw (GtkWidget* widget, GdkEventExpose* event) {
if (event->count > 0) {
return(TRUE);
}
g_print ("Expose Event\n");
if (gtk_gl_area_make_current(GTK_GL_AREA(widget))) {
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* */
/* Insert your drawing code here. */
/* */
gtk_gl_area_swapbuffers (GTK_GL_AREA(widget));
}
return (TRUE);
}

gint
glarea_reshape (GtkWidget* widget, GdkEventConfigure* event) {
int w = widget->allocation.width;
int h = widget->allocation.height;
g_print ("Reshape Event\n");
if (gtk_gl_area_make_current (GTK_GL_AREA(widget))) {
/* This is an example 2D reshape function. Writing reshape */
/* functions is beyond the scope of this demo. Check the */
/* red book or the www.opengl.org for more information on */
/* how to write reshape code to suit your needs. */
glViewport (0, 0, w, h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluOrtho2D (-(w>>1), (w>>1), -(h>>1), h>>1);
glMatrixMode (GL_MODELVIEW);
}
return (TRUE);
}

gint
glarea_init (GtkWidget* widget) {
g_print ("Realize Event\n");
if (gtk_gl_area_make_current (GTK_GL_AREA(widget))) {
/* Insert your OpenGL initialization code here */
}
return TRUE;
}

gint
glarea_destroy (GtkWidget* widget) {
g_print ("GTK GL Area Destroy Event\n");
/* Insert any required cleanup */
/* code here. */
return TRUE;
}

int
main (int argc, char** argv) {
GtkWidget* window;
GtkWidget* button_quit;
GtkWidget* box_main;
GtkWidget* glarea;
/* These attributes are passed to glXChooseVisual by the */
/* gdk (see gdk_gl_choose_visual in gdkgl.c from the GtkGlarea distro). */
int attrlist[] = {
GDK_GL_RGBA,
GDK_GL_DOUBLEBUFFER,
GDK_GL_DEPTH_SIZE, 1,
GDK_GL_NONE
};
gtk_init (&argc, &argv);
if(gdk_gl_query() == FALSE) {
g_print("OpenGL not supported!\n");
return (1);
}

window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW(window), "GtkGLArea Demo For Blogger");
gtk_quit_add_destroy (1, GTK_OBJECT(window));
gtk_signal_connect (GTK_OBJECT(window), "delete_event", GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
gtk_container_set_border_width (GTK_CONTAINER(window), 10);
gtk_widget_show (window);

box_main = gtk_vbox_new (FALSE, 10);
gtk_container_add (GTK_CONTAINER(window), box_main);
gtk_widget_show (box_main);

glarea = gtk_gl_area_new(attrlist);
gtk_widget_set_events(GTK_WIDGET(glarea),
GDK_EXPOSURE_MASK|
GDK_BUTTON_PRESS_MASK);
gtk_signal_connect (GTK_OBJECT(glarea), "button_press_event", GTK_SIGNAL_FUNC(glarea_button_press), NULL);
gtk_signal_connect (GTK_OBJECT(glarea), "expose_event", GTK_SIGNAL_FUNC(glarea_draw), NULL);
gtk_signal_connect (GTK_OBJECT(glarea), "configure_event", GTK_SIGNAL_FUNC(glarea_reshape), NULL);
gtk_signal_connect (GTK_OBJECT(glarea), "realize", GTK_SIGNAL_FUNC(glarea_init), NULL);
gtk_signal_connect (GTK_OBJECT(glarea), "destroy", GTK_SIGNAL_FUNC (glarea_destroy), NULL);
gtk_widget_set_usize(GTK_WIDGET(glarea), 256, 256);
gtk_box_pack_start (GTK_BOX(box_main), glarea, FALSE, TRUE, 0);
gtk_widget_show (glarea);

button_quit = gtk_button_new_with_label ("Quit");
gtk_signal_connect (GTK_OBJECT(button_quit), "clicked", GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
gtk_box_pack_start (GTK_BOX(box_main), button_quit, FALSE, TRUE, 0);
gtk_widget_show (button_quit);

gtk_main ();

return (0);
}


И компиллируем его следующей командой:
#gcc gtkglarea_demo.c -o gtkglarea_demo `pkg-config gtk+-2.0 glib-2.0 gtkgl-2.0 --cflags --libs`
Запускаем на выполнение gtkglarea_demo и видим диалоговое окно с черным квадратом, что и есть (пустая) сцена OpenGL и кнопкой выхода под нашим виджетом.
Файл gtkglarea.h содержится в пакете libgtkgl2.0-dev.
Рассмотрим теперь "конкурента", то есть gtkglext.
Аналогично, создаем файл gtkglext_demo.c с содержимым (он является упрощенной и измененной версией файла simple.c из пакета libgtkglext1-dev):


#include <stdlib.h>
#include <gtk/gtk.h>
#include <gtk/gtkgl.h>
#include <GL/gl.h>
#include <GL/glu.h>

static void
realize (GtkWidget *widget, gpointer data){
GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);

if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
return;

glClearColor (0.0, 0.0, 0.0, 0.0);
glClearDepth (1.0);
glViewport (0, 0, widget->allocation.width, widget->allocation.height);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (40.0, 1.0, 1.0, 10.0);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
gluLookAt ( 0.0, 0.0, 3.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
glTranslatef (0.0, 0.0, -3.0);

gdk_gl_drawable_gl_end (gldrawable);
}

static gboolean
configure_event (GtkWidget *widget, GdkEventConfigure *event, gpointer data){
GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);

if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
return FALSE;
glViewport (0, 0, widget->allocation.width, widget->allocation.height);
gdk_gl_drawable_gl_end (gldrawable);

return TRUE;
}

static gboolean
expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data){
GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);

if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
return FALSE;
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (gdk_gl_drawable_is_double_buffered (gldrawable))
gdk_gl_drawable_swap_buffers (gldrawable);
else
glFlush ();
gdk_gl_drawable_gl_end (gldrawable);

return TRUE;
}

int
main (int argc, char *argv[]){
GdkGLConfig *glconfig;
gint major, minor;
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *drawing_area;
GtkWidget *button;

gtk_init (&argc, &argv);
gtk_gl_init (&argc, &argv);
gdk_gl_query_version (&major, &minor);
g_print ("\nOpenGL extension version - %d.%d\n",major, minor);

glconfig = gdk_gl_config_new_by_mode ( GDK_GL_MODE_RGB |
GDK_GL_MODE_DEPTH |
GDK_GL_MODE_DOUBLE);
if (glconfig == NULL){
glconfig = gdk_gl_config_new_by_mode ( GDK_GL_MODE_RGB |
GDK_GL_MODE_DEPTH);
if (glconfig == NULL)
exit (1);
}

window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "GtkGLExt Demo For Blogger");
gtk_container_set_reallocate_redraws (GTK_CONTAINER (window), TRUE);
g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (gtk_main_quit), NULL);
gtk_container_set_border_width (GTK_CONTAINER(window), 10);
gtk_widget_show (window);

vbox = gtk_vbox_new (FALSE, 10);
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_widget_show (vbox);

drawing_area = gtk_drawing_area_new ();
gtk_widget_set_size_request (drawing_area, 256, 256);
gtk_widget_set_gl_capability ( drawing_area,
glconfig,
NULL,
TRUE,
GDK_GL_RGBA_TYPE);
g_signal_connect_after (G_OBJECT (drawing_area), "realize", G_CALLBACK (realize), NULL);
g_signal_connect (G_OBJECT (drawing_area), "configure_event", G_CALLBACK (configure_event), NULL);
g_signal_connect (G_OBJECT (drawing_area), "expose_event", G_CALLBACK (expose_event), NULL);
gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);
gtk_widget_show (drawing_area);

button = gtk_button_new_with_label ("Quit");
g_signal_connect (G_OBJECT (button), "clicked",G_CALLBACK (gtk_main_quit), NULL);
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);

gtk_main ();

return 0;
}


Компиллируем
#gcc gtkglext_demo.c -o gtkglext_demo `pkg-config gtk+-2.0 glib-2.0 gtkglext-1.0 --cflags --libs`
И получаем исполняемый файл gtkglext_demo, который дает тот же результат, что и предыдущий пример, только заголовок окна приложения соответственно изменен.
Коротко обсудим разницу между этими двумя протыми приложениями.
Интерфейс gtkglarea можно посмотреть в файле gtkglarea.h из пакета libgtkgl2.0-dev.
Там можно увидеть, что этот виджет является прямым потомком виджета GtkDrawingArea. Еще одним полем в структуре, соответствующей этому виджету, есть переменная типа GdkGLContext. И в первом примере мы с этим виджетом обращаемся стандартно: создаем его своим собственным конструктором, пакуем, устанавливаем сигналы, показываем. Когда рисуем в этот виджет, то пользуемся функцией gtk_gl_area_make_current.
В случае с gtkglext работа происходит несколько иначе. Создается объект типа GdkGLConfig и потом он "привязывается" к виджету GtkDrawingArea. Затем, когда посылаем команды OpenGL в этот виджет, то создаем объекты типа GdkGLContext и GdkGLDrawable, после чего заключаем команды OpenGL в "функциональные скобки" gdk_gl_drawable_gl_begin и gdk_gl_drawable_gl_end.
Оба примера были протестированы на squeeze Debian.

воскресенье, 31 октября 2010 г.

Как "нарисовать" математическую формулу с помощью OOoLatex

OOoLatex - это плагин к OpenOffice, позволяющий пользоваться возможностями LaTeX в этом офисном пакете. Короче - создавать математические формулы в документах опенофиса.
Сначала проинсталлируем его (плагин). Находим с помощью какой-либо поисковой системы домашнюю страницу плагинов к OpenOffice и находим далее в списке OOoLatex. Точнее его tar.gz архив. Выкачиваем. И распаковываем, где нам удобно.Это будет директория с именем типа: OOoLatexMacro-2005.10.19a. В ней будет два важных для нас подкаталога: bin и macro-2.0 .
Далее открываем OpenOffice и через меню идем по такому "пути":Tools -> Macros -> Organize Macros -> OpenOffice.org Basic -> Organizer -> Libraries -> Import и находим файл script.xlb в директории macro-2.0
При конфигурировании надо указать полный путь к файлу OOoLatex. Он находится в упомянутом каталоге bin.
Теперь можно писать математические формулы, но не это главное в этом посте.
Создаем файл test.tex:

\documentclass[10pt]{article}
\usepackage{amsmath}
\usepackage{amssymb}
%%%
\usepackage{color}
\definecolor{bg}{RGB}{255,255,255}
\definecolor{fg}{RGB}{0,0,0}
\pagecolor{bg}
\color{fg}
%%%
\pagestyle{empty}
\begin{document}
\[\iint\cos\theta(\vec r) dx dy \]
\end{document}

И запускаем на выполнение из директории где создан этот файл следующую команду:
#/path/to/my/ooolatex/bin/OOoLatex -e png test.tex

Будет создан "компактный" файл в формате png, который вы сможете вставлять в любой документ, который поддерживает такие "вставки": веб страница, произвольный графический редактор, документ опенофиса.

вторник, 24 августа 2010 г.

Простейшая установка сервиса samba

Установим пакеты samba, samba-common, smbclient, smbfs.
# smbd --version
Version 3.2.5

Испоняемые файлы из пакета samba:

/usr/bin/eventlogadm
/usr/bin/smbstatus
/usr/bin/smbcontrol
/usr/bin/profiles
/usr/bin/tdbbackup
/usr/bin/pdbedit
/usr/sbin/smbd
/usr/sbin/nmbd
/usr/sbin/mksmbpasswd

Исполняемые и конфигурационные файлы из пакета samba-common:

/usr/bin/net
/usr/bin/nmblookup
/usr/bin/smbpasswd
/usr/bin/testparm
/usr/share/samba/smb.conf

Исполняемые файлы из пакета smbclient:

/usr/bin/findsmb
/usr/bin/smbclient
/usr/bin/smbget
/usr/bin/smbtar
/usr/bin/rpcclient
/usr/bin/smbspool
/usr/bin/smbtree
/usr/bin/smbcacls
/usr/bin/smbcquota

Исполняемые файлы из пакета ssmbfs:

/sbin/mount.smbfs
/sbin/mount.cifs
/sbin/umount.cifs
/usr/sbin/cifs.upcall
/usr/bin/smbumount
/usr/bin/smbmount

Добавим в /etc/samba/smb.conf такие строчки:

[nameOfResource]
path = /home/someuser/existing
Pathcomment = our comment
available = yes
browsable = yes
public = yes
writable = no

Теперь, после перезагрузки samba, если в Nautilus набрать строчку smb://netbiosname/nameOfResource, то мы получим доступ (для чтения) к каталогу /home/someuser/existingPath на машине netbiosname. Пароли пользователей хранятся в passdb.tdb

Минимальный набор функций OpenGL для работы с текстурами

1)
a)Первым необходимым шагом при наложении карты текстуры на геометрический объект является загрузка текстуры в память. Загруженная текстура становиться частью текущего "состояния текстуры". Для этой загрузки используются функции
void glTexImage{N}D(...);
Текстура грузится из памяти, на которую указывает указатель, являющийся последним аргументом этих функций.Или одно- и двух- мерные текстуры можно загрузить также из буфера цвета:
void glCopyTexImage{1,2}D(...);
К загруженным данным текстуры применяются упаковка пикселей, масштабирование пикселей таблицы цветов, свертки и т.д.
b)Чтобы пользоваться этими функциями необходимо включить или выключить данное состояние текстуры:
glDisable(GL_TEXTURE_{M}D);
glEnable(GL_TEXTURE_{N}D);

2)То, как OpenGL объединяет цвета текселей с цветом геометрического объекта, на который накладывается текстура, зависит от режима текстурной среды, который устанавливается функцией glTexEnv.Правила визуализации и поведение применяющихся карт текстуры можно также изменением параметров функций семейства glTexParameter.
3)Далее надо задать текстурные координаты вершин (То есть присвоение вершинам объекта, на который накладываем текстуру, "координат" в "пространстве" текстуры). Обращение к текселям карты текстуры выполняется не как к ячейкам памяти (как для пиксельных образов), а как к абстрактным текстурным координатам (переменные с плавающей запятой в диапазоне от 0 до 1):
void glTexCoord{N}f(...);
Эта функция вызывается между glBegin и glEnd, перед соответствующей функцией glVertex{N}x(...);Для работы с несколькими текстурами и более быстрого переключения между ними используются функции:
a)glGenTextures - принимает в качестве параметров указатель на массив целых чисел и его размер. Эти целые числа играют роль идентификаторов текстур (текстурных объектов).
b)glBindTexture - делает текущим выбранный текстурный объект.
c)glDeleteTextures - освобождает ресурсы, занятые текстурными объектами.

среда, 9 июня 2010 г.

Пример использования LAPACK, BLAS и ATLAS в Дебиан

Рассмотрим сначала использование LAPACK. Для начала создадим файл lapack.c следующего содержания:
$ cat lapack.c


/* Example C code for solving a linear system Ax=b using LAPACK */
#include <stdio.h>

/* Declare function prototype */
extern int sgesv_(int *n, int *nrhs, float *a, int *lda,
int *ipiv, float *b, int *ldb, int *info);

/* -- LAPACK driver routine (version 3.1) --
Purpose
=======

SGESV computes the solution to a real system of linear equations
A * X = B,
where A is an N-by-N matrix and X and B are N-by-NRHS matrices.

The LU decomposition with partial pivoting and row interchanges is
used to factor A as
A = P * L * U,
where P is a permutation matrix, L is unit lower triangular, and U is
upper triangular. The factored form of A is then used to solve the
system of equations A * X = B.

Arguments
=========

N (input) INTEGER
The number of linear equations, i.e., the order of the
matrix A. N >= 0.

NRHS (input) INTEGER
The number of right hand sides, i.e., the number of columns
of the matrix B. NRHS >= 0.

A (input/output) REAL array, dimension (LDA,N)
On entry, the N-by-N coefficient matrix A.
On exit, the factors L and U from the factorization
A = P*L*U; the unit diagonal elements of L are not stored.

LDA (input) INTEGER
The leading dimension of the array A. LDA >= max(1,N).

IPIV (output) INTEGER array, dimension (N)
The pivot indices that define the permutation matrix P;
row i of the matrix was interchanged with row IPIV(i).

B (input/output) REAL array, dimension (LDB,NRHS)
On entry, the N-by-NRHS matrix of right hand side matrix B.
On exit, if INFO = 0, the N-by-NRHS solution matrix X.

LDB (input) INTEGER
The leading dimension of the array B. LDB >= max(1,N).

INFO (output) INTEGER
= 0: successful exit
< 0: if INFO = -i, the i-th argument had an illegal value
> 0: if INFO = i, U(i,i) is exactly zero. The factorization
has been completed, but the factor U is exactly
singular, so the solution could not be computed.

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

#define SIZE 3 /* dimension of matrix */

static int solve(float A[][SIZE], float *b) {

int i,j,info,n,nrhs,lda,ipiv[SIZE],ldb;
float AT[SIZE*SIZE];

/* Permute matrix */
for (i=0; i<SIZE; i++) {
for(j=0; j<SIZE; j++)
AT[j*SIZE+i]=A[i][j];
}

/* Invoke sgesv_ */
n = lda = ldb = SIZE; nrhs = 1;
sgesv_(&n, &nrhs, AT, &lda, ipiv, b, &ldb, &info);
return info;
}

int main(int argc, char **argv)
{
int i, j, pivot[SIZE], ok;
float A[SIZE][SIZE], b[SIZE];

/* Matrix A */
A[0][0]= 1.1; A[0][1]= 2.2; A[0][2]=-3.3;
A[1][0]= 4.4; A[1][1]=-5.5; A[1][2]= 6.6;
A[2][0]=-7.7; A[2][1]= 8.8; A[2][2]= 9.9;

/* Define right hand side vector */
b[0] = 0;
b[1] = 5.5;
b[2] = 11;

/* Call warpper function */
ok = solve(A, b);

/* Print out solution vector x */
for (j=0; j<SIZE; j++)
printf("%g\n", b[j]);
}



Компиллируем этот код с помощью команды:
$ gcc lapack.c -o lapack -llapack

Смотрим - какие пакеты нам нужны (просто для информации)
$ apt-file search /usr/lib/liblapack.so
lapack3: usr/lib/liblapack.so.3
lapack3: usr/lib/liblapack.so.3.0
lapack3-dev: usr/lib/liblapack.so


Рассмотрим теперь пример использования BLAS и еще один пример использования LAPACK в одном файле. Создадим файл blas.c такого содержания:
$ cat blas.c



#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <cblas.h>
#include <clapack.h>

int clapack_sgetrf(const enum CBLAS_ORDER Order, const int M, const int N, float *A, const int lda, int *ipiv);
// a is a column-major array of all the values in the matrix to invert
// The matrix's height and width are the same because it is a square matrix.
void invertMatrix(float *a, unsigned int height)
{
int info, ipiv[height];
info = clapack_sgetrf(CblasColMajor, height, height, a, height, ipiv);
info = clapack_sgetri(CblasColMajor, height, a, height, ipiv);
}

void displayMatrix(float *a, unsigned int height, unsigned int width)
{
int i, j;
for(i = 0; i < height; i++)
{
for(j = 0; j < width; j++)
{
printf("%1.3f ", a[height*j + i]);
}
printf("\n");
}
printf("\n");
}

void multiplyMatrix(float *a, unsigned int aheight, unsigned int awidth, float *b, unsigned int bwidth, float *c)
{
cblas_sgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, aheight, bwidth, awidth, 1.0f, a, aheight, b, awidth, 0.0f, c, aheight);
}

int main(int argc, char *argv[])
{
int i;
float a[9], b[9], c[9];
srand(time(NULL));
for(i = 0; i < 9; i++)
{
a[i] = 1.0f*rand()/RAND_MAX;
b[i] = a[i];
}
displayMatrix(a, 3, 3);
invertMatrix(a, 3);
multiplyMatrix(a, 3, 3, b, 3, c);
displayMatrix(c, 3, 3);
return 0;
}

Компиллируем его:
$ gcc blas.c -o blasAndLapackUsage -llapack -L /usr/lib/atlas
Посмотрим дополнительную информацию про файлы, которые нужны для компиляции этого примера:
$ apt-file search /usr/include/clapack.h
atlas3-headers: usr/include/clapack.h
$ apt-file search /usr/include/cblas.h
refblas3-dev: usr/include/cblas.h
$ apt-file search /usr/lib/liblapack.so
lapack3: usr/lib/liblapack.so.3
lapack3: usr/lib/liblapack.so.3.0
lapack3-dev: usr/lib/liblapack.so

$ apt-file search /usr/lib/atlas
atlas3-base: usr/lib/atlas/libblas.so.3
atlas3-base: usr/lib/atlas/libblas.so.3.0
atlas3-base: usr/lib/atlas/liblapack.so.3
atlas3-base: usr/lib/atlas/liblapack.so.3.0
atlas3-base-dev: usr/lib/atlas/libblas.a
atlas3-base-dev: usr/lib/atlas/libblas.so
atlas3-base-dev: usr/lib/atlas/liblapack.a
atlas3-base-dev: usr/lib/atlas/liblapack.so

Другие полезные ссылки по теме:
ATLAS FAQ
Example C code for solving a linear system Ax=b using LAPACK
Compiling Programs Containing LAPACK Routines
LAPACK build and test guide
Using Lapack Routines in C Programs
netlib, Frequently Asked Questions
BLAS Frequently Asked Questions (FAQ)
GNU Scientific Library -- Reference Manual
Driver Routines
The Linear Algebra Package

суббота, 29 мая 2010 г.

Пример использования GNU Scientific Library (GSL) в Дебиан

Этот исходник взят с GSL-CBLAS-Examples
#cat gsl-cblas.c
Описание функций из библиотеки GSL находиться здесь.

#include <stdio.h>
#include <gsl/gsl_cblas.h>
int
main (void)
{
int lda = 3;
float A[] = { 0.11, 0.12, 0.13,
0.21, 0.22, 0.23 };
int ldb = 2;
float B[] = { 1011, 1012,
1021, 1022,
1031, 1032 };
int ldc = 2;
float C[] = { 0.00, 0.00,
0.00, 0.00 };
/* Compute C = A B */
cblas_sgemm (CblasRowMajor,
CblasNoTrans, CblasNoTrans, 2, 2, 3,
1.0, A, lda, B, ldb, 0.0, C, ldc);
printf ("[ %g, %g\n", C[0], C[1]);
printf (" %g, %g ]\n", C[2], C[3]);
return 0;
}

Процедура просто перемножает две матрицы. Ее описание тут.
Чтобы откомпиллировать этот исходник командой
#gcc -o gsl-cblas gsl-cblas.c -lblas
нам необходимы файлы libblas.so и libblas.so.
#apt-file search /usr/lib/libblas.so
refblas3: usr/lib/libblas.so.3
refblas3: usr/lib/libblas.so.3.0
refblas3-dev: usr/lib/libblas.so

# ls -al /usr/lib/libblas.so
lrwxrwxrwx 1 user user 12 2009-08-06 14:44 /usr/lib/libblas.so -> libblas.so.3
# apt-file search /usr/include/gsl/gsl_cblas.h
libgsl0-dev: usr/include/gsl/gsl_cblas.h
libgsl0-dev: usr/include/gsl/gsl_cblas.h

Вывод команды ./gsl-cblas:
[ 367.76, 368.12
674.06, 674.72 ]
Этот исходник можно откомпиллировать также с помощью команды:
#gcc -Wall gsl-cblas.c -lgslcblas
Для успешной компилляции нужен установленный пакет libgsl0:
#ls -al /usr/lib/libgslcblas.so
lrwxrwxrwx 1 user user 20 2009-12-17 16:45 /usr/lib/libgslcblas.so -> libgslcblas.so.0.0.0
#ls -al /usr/lib/libgslcblas.so.0.0.0
-rw-r--r-- 1 user user 188936 2006-11-19 03:26 /usr/lib/libgslcblas.so.0.0.0
#apt-file search /usr/lib/libgslcblas.so.0.0.0
libgsl0: usr/lib/libgslcblas.so.0.0.0

Как найти пакеты, от которых зависит во время сборки данный бинарный файл в Дебиан

Делаем
$ objdump -p /usr/bin/myProgramm | grep NEEDED
Это вывод файлов, от которые нужны при постройке myProgramm. Пусть это будет такой вывод:
NEEDED libblas.so.3
NEEDED libc.so.6

Далее каждого такого файла делаем команду dpkg -S:
$ dpkg -S /usr/lib/libblas.so.3
Вывод будет такой:
refblas3: /usr/lib/libblas.so.3
Более развернутый вывод будет у команды
$ apt-file search /usr/lib/libblas.so.3
refblas3: usr/lib/libblas.so.3
refblas3: usr/lib/libblas.so.3.0

То есть при построении программы myProgramm понадобиться библиотека libblas.so.3 из пакета refblas3

четверг, 29 апреля 2010 г.

Временные задержки (таймауты) в Sendmail

Sendmail позволяет изменять timeout-ы для разных фаз почтовой транзакции. Значения по умолчанию некоторых таймаутов нелепо велики по сравнению с рекомендуемыми RFC значениями. Вот возможные значения таймаутов, установив которые в конфигурационном файле senmail-a, можно будет разгрузить систему:
define(`confTO_ICONNECT', `15s')dnl
define(`confTO_CONNECT', `3m')dnl
define(`confTO_HELO', `2m')dnl
define(`confTO_MAIL', `1m')dnl
define(`confTO_RCPT', `1m')dnl
define(`confTO_DATAINIT', `1m')dnl
define(`confTO_DATABLOCK', `1m')dnl
define(`confTO_DATAFINAL', `1m')dnl
define(`confTO_RSET', `1m')dnl
define(`confTO_QUIT', `1m')dnl
define(`confTO_MISC', `1m')dnl
define(`confTO_COMMAND', `1m')dnl
define(`confTO_STARTTLS', `2m')dnl

По умолчанию у таймаутов стоят такие значения:
confTO_INITIAL [5m]
confTO_CONNECT [0]
confTO_ACONNECT [0]
confTO_HELO [5m]
confTO_MAIL [10m]
confTO_RCPT [1h]
confTO_DATAINIT [5m]
confTO_DATABLOCK [1h]
confTO_DATAFINAL [1h]
confTO_RSET [5m]
confTO_QUIT [2m]
confTO_MISC [2m]
confTO_COMMAND [1h]
confTO_IDENT [5s]
confTO_FILEOPEN [60s]
confTO_LHLO [2m]
confTO_AUTH [10m]
confTO_STARTTLS [1h]
confTO_CONTROL [2m]
confTO_QUEUERETURN [5d]
confTO_QUEUEWARN [4h]
confTO_HOSTSTATUS [30m]

Следующие таймауты неопределены:
confTO_ICONNECT Timeout.iconnect
confTO_QUEUERETURN_NORMAL
confTO_QUEUERETURN_URGENT
confTO_QUEUERETURN_NONURGENT
confTO_QUEUERETURN_DSN
confTO_QUEUEWARN_NORMAL
confTO_QUEUEWARN_URGENT
confTO_QUEUEWARN_NONURGENT
confTO_QUEUEWARN_DSN

confTO_RESOLVER_RETRANS
confTO_RESOLVER_RETRANS_FIRST
confTO_RESOLVER_RETRANS_NORMAL
confTO_RESOLVER_RETRY
confTO_RESOLVER_RETRY_FIRST
confTO_RESOLVER_RETRY_NORMAL

Апгрейд с lenny на sqeeze

Аналогичные действия делаем при переходе с etch на lenny.
#sudo vim /etc/apt/sources.list
Заменить каждое слово "lenny" на слово "squeeze" ("etch" на "lenny").
Ну и наконец:
#sudo aptitude update
#sudo aptitude install apt dpkg aptitude
#sudo aptitude full-upgrade

понедельник, 5 апреля 2010 г.

Диагностика установки сервиса samba

Приведем стандартную последовательность поиска причин проблем связанных с настройкой сервера samba.
Пусть samba дает доступ к ресурсу:
[sharedFolder]
path=/sharedFolder

1)Просканировать порты 137, 138 и 139. Открыты ли они.
2)Применить утилиту testparm для проверки синтаксиса файла конфигурации smb.conf.
3)Проверить, запущены ли процессы nmbd и smbd.
3)Проверить сетевое соединение и TCP/IP. Это делают утилиты ping, ipconfig /all, ipconfig, etc.
4)Проверить разрешение имен DNS. Это делается утилитами nslookup или dig. При невозможности доступа к ДНС проверить нет ли в файле конфигурации smb.conf записи dns proxy = no.
5)Отобразить перечень ресурсов для общего использования на сервере:
#smbclient -L nameSambaServer
6)Проверить верно ли работает преобразование NetBIOS-имени:
#nmblookup -B nameSambaServer __SAMBA__
7)
#nmblookup -B x.x.x.x '*'
Определяются имена всех компьютеров, которые отвечают под адресом х.х.х.х.
#nmblookup -B x.x.x.x nameClient
Ищется конкретный компьютер с именем nameClient из списка найденного первой командой.
8)Проверить, какие компьютеры отвечают на запросы NetBIOS. Все компьютеры должны выдать сообщение "got a positive name query response". Если ни один компьютер не выдаст своего IP-адреса, то это ошибка в широковещательном адресе. Можно добавить в конфигурационный файл опцию interface. Если компьютер находится в другой подсети, то воспользоваться ключем -B.
9)
#smbclient //nameSambaServer/sharedFolder
Если все в порядке, то происходит smb-приглашение: smb>_
Возможные причины ошибки bad password

  • Пользователь отсутствует в перечне valid users

  • Параметр password level недостаточно высок

  • Неверный параметр path в файле smb.conf

  • Отсутствует файл smbpasswd


10)Получить список ресурсов сервера:
#net view \\nameSambaServer
11)Внимательно посмотреть на параметры host allow и host deny.
12)Проверить файлы /etc/hosts.allow /etc/hosts.deny.
13)
#net use x: //nameSambaServer/sharedFolder
Дожно появиться сообщение "command completed successfully".

пятница, 5 февраля 2010 г.