Un clon, por si las moscas

Que ciertas empresas pueden traicionar (o defraudar) a la comunidad sin previo aviso es algo que muchos sabemos desde hace mucho tiempo. Desgraciadamente, aun sabiéndolo, solemos olvidarlo o restarle importancia.

Uno de los ejemplos históricos más claros fue el de Sun Microsystems, que aunque impulsó fuertemente el software libre, también hizo lo contrario en los últimos años antes de ser fagocitada por Oracle. Y Oracle, claro está, fue peor aún. Otro ejemplo no tan recordado fue EyeOS, de mi «queridísimo» Pau García Milà (me robaba la comida en la oficina, aparte de programar como un chimpancé y enseñarnos el culo cuando se dignaba a pasar por las oficinas de Bananity).

Recientemente ha habido otro caso muy sonado, en el que Apple ha hecho desaparecer sin previo aviso los repositorios completos de FoundationDB en Github. Este no será nunca el caso de ColorSharp, ni el código es tan apetecible para una macrocorporación, ni yo permitiría que algo así sucediera. Sin embargo, visto lo visto, es mejor tomar precauciones: Github podría perder sus datos por un accidente, cerrar por algún problema económico (aunque no es creíble a corto plazo), censurar algunos repositorios (como de hecho sucedió, por tener que aplicar ciertas leyes estadounidenses)…

Por eso mismo he decidido mantener un mirror del proyecto en Gitlab: https://gitlab.com/Litipk/ColorSharp . Puntualizo, aunque el código de Gitlab es libre (a diferencia del de Github), me fío tanto de ellos como de los primeros. Que el código sea libre no los hace menos vulnerables a los problemas que he mencionado. Este clon no es para saltar de Github a Gitlab, sinó mas bien asegurar que habrá como mínimo un mirror. Y me estoy planteando crear otro en Bitbucket.

Apuntes y reflexión breve

Buenas.

Desde hace unas dos semanas no ha habido demasiado movimiento en el desarrollo de ColorSharp. Sin embargo han sucedido suficientes cosas como para que valga la pena escribir sobre ello.

En la entrada anterior comenté como había realizado algunos esfuerzos para ponérselo fácil a la comunidad y que alguien se animara a contribuir al proyecto. A lo que comenté, debo añadir que también creé una lista de correo para quien quiera discutir sobre lo que sea más pausada y organizadamente de lo que permite un chat tipo IRC.

De momento, tanto la sala de chat como la lista de correo están completamente muertas. Es normal, el proyecto sigue sin ser conocido y es de nicho, además de estar relativamente verde todavía. Considero que la estructura y el plan de desarrollo permitirán que la biblioteca supere en flexibilidad y funcionalidad a las otras bibliotecas de conversión de color que existen para .NET (de hecho ya las supera en algunos puntos), pero de momento lo conseguido sigue siendo insuficiente.

Continuando con el asunto de la actividad, por suerte no ha sido todo malo. Añadí mi proyecto a la página de Up for Grabs, y, oh casualidad, al día siguiente tenía un «pull request» pendiente de revisión para ColorSharp 🙂 . Debo decir que aun no lo he integrado porque tengo que hacer más pruebas, pero debería darme brío para no desanimar al colaborador recién llegado. Además, me sorprendí viendo en mi buzón dos emails de dudas relativas a ColorSharp, aunque fueron enviados a titulo particular y no a la lista de correo. El asunto de los canales de comunicación debe ser tratado.

Otro punto que tenía pendiente hasta hace nada era la documentación. Finalmente he rellenado la wiki con explicaciones sobre la estructura de ColorSharp y como usar el proyecto.

Si nos fijamos en los artículos anteriores, podemos ver que mucho de lo que he comentado y me he propuesto sigue en el limbo. La creación de comunidad y asegurar que la experiencia «out of the box» es buena han sido los puntos que más han centrado mi atención la mayor parte del tiempo.

Parece mentira, pero pequeñas sutilezas pueden marcar una diferencia enorme en la actividad del proyecto y en la percepción que se tiene de él. Por ejemplo, actualmente tengo una lista TODO en un fichero dentro del repositorio, desde luego eso es mejor que nada, pero por muchos motivos es subóptimo.

Mi próximo movimiento, antes de tocar una sola línea de código, será mover toda esa información al bugtracker de Github. Esto servirá no solo para visibilizar la necesidad de «mano de obra» sino también para obtener una mejor visión sobre el progreso del proyecto.

Saludos!

Nueva versión: 0.10.0

Buenas 🙂 , aquí llega una nueva versión con novedades interesantes, tanto en la gestión como en la propia biblioteca.

Mejoras en la gestión del proyecto

En primer lugar, estoy haciendo algunos esfuerzos para facilitar que desarrolladores externos puedan y/o quieran contribuir al desarrollo de ColorSharp.

El primer cambio interesante, aunque ha supuesto ningún esfuerzo, es integrar el repositorio de ColorSharp en Github con el servicio Gitter; desde ahora ColorSharp tiene una sala dedicada de chat, tipo IRC. Se puede acceder a este chat a tanto a través de su página web como a través de diversas aplicaciones móviles.

Otro cambio menor es que finalmente tenemos una guía para contribuir al proyecto. Es muy probable que esta guía tenga que cambiar mucho dado que hasta ahora ColorSharp ha sido un proyecto fundamentalmente unipersonal.

Como extra, y por el momento sólo de forma experimental, estoy empezando a trastear con Gitcolony para gestionar la revisión de commits y «pull requests». Parece una herramienta muy interesante (aunque privativa :(, todo sea dicho) para gestionar las revisiones de código de forma más o menos automatizada y bien organizada.

Cambios interesantes

  • Añadidos los illuminants B, C, D50 y D55.
  • Añadida una clase para generar espectros lumínicos de cuerpos negros para una temperatura dada.
  • Añadidas las funciones de matching de 1964 (10º) de la CIE.
  • Reemplazado las funciones de matching ed 1931 (2º) de la CIE con datos más precisos.
  • Mejoras menores en la conversión espectro->color:
    • Separadas las estrategias de conversión espectro->color de las estrategias para conversiones color->color.
    • Ahora es posible escoger entre las funciones de matching de 2º y 10º.
  • Mejorada la documentación XML.
  • Eliminada la dependencia de la biblioteca MathNet.Numerics.

Ideas que han surgido sobre la marcha

Durante estos días en que he estado realizando los cambios de esta versión he descubierto un proyecto muy interesante: Public Lab, en especial uno de sus subproyectos, Spectral Workbench. Esto me ha hecho pensar que podría ser interesante integrar en la biblioteca una forma de interactuar con la API de Spectral Workbench para importar o exportar espectros.

Bien, de momento no hay muchas más novedades que comentar. Os dejo con esto, y como siempre, os invito a colaborar 🙂 , y más ahora que os lo estoy poniendo más fácil.

Nueva versión: 0.9.1

Buenas,

hoy he liberado una nueva versión de ColorSharp (0.9.1). La lista de cambios no es demasiado larga, son los siguientes:

  • Añadido el espacio de color CIE UVW (1960).
  • Conversiones menos destructivas (ahora la información se preserva mejor)
  • Ahora los métodos ToSRGB, ToCIExyY y ToCIEUVW son virtuales y no abstractos para reutilizar código y facilitar la implementación de nuevos espacios de color. Esto se puede hacer gracias a la centralidad del espacio CIE XYZ (1932) dentro de la teoría de colorimetría.
  • Actualizada la dependencia MathNet.Numerics.

No hay mucho más que contar al respecto. Como siempre, os animo a colaborar y a preguntar si tenéis dudas 🙂 .

Saludos!

P.D. (Edición posterior) :

Después de liberar la versión 0.9.1 he introducido dos ligeras novedades en el desarrollo y distribución de ColorSharp:

  • Ahora también distribuyo los paquetes de NuGet a través de Github (en la sección releases), para no depender exclusivamente de nuget.org . Esto puede ahorrar muchos quebraderos de cabeza si la biblioteca se usa para desarrollos empresariales y nuget.org falla.
  • Por fin he añadido soporte a Travis CI 🙂 , antes era relativamente complicado, se tenía que trampear un poco el sistema, pero desde hace poco se le da soporte (beta) a Mono. Con este cambio todos los commits dispararán la ejecución de los tests dentro del entorno de integración contínua. Esto sirve para facilitar la integración de código ajeno (reduciendo el tiempo necesario de revisión), y para que cualquiera pueda hacerse una idea sobre la calidad del código sin tener que ejecutar sus propios tests.

Aproximación tímida a Pash

En el artículo anterior mencioné Pash sin entrar demasiado en los detalles sobre su desarrollo. Como ya comenté, esta herramienta me interesa debido a que puede llegar a ser crucial para el desarrollo de software libre ligado a Mono y otras tecnologías .NET.

Ayer creé una entrada para Pash en la AppDB de Wine (y soy el mantenedor oficial de ésta), además de un un «test». Todas las pruebas que hice concluyen que Pash funciona relativamente bien en Wine (usando el reemplazo basado en Mono que proveen para .NET), salvo por unos mensajes de debug bastante molestos cuando se inicia la aplicación, y que reproduzco aquí (donde escribo [...] significa que se repite más de lo mismo):

fixme:heap:HeapSetInformation (nil) 1 (nil) 0
fixme:process:GetProcessWorkingSetSize (0xffffffff,0x153e92c,0x153e930): stub
fixme:win:RegisterDeviceNotificationA (hwnd=0x14b270, filter=0x253e5dc,flags=0x00000001) returns a fake device notification handle!
[...]
fixme:win:UnregisterDeviceNotification (handle=0xcafecafe), STUB!
fixme:win:RegisterDeviceNotificationA (hwnd=0x14b270, filter=0x253e5dc,flags=0x00000001) returns a fake device notification handle!
fixme:win:UnregisterDeviceNotification (handle=0xcafecafe), STUB!

Dichos mensajes de debug son de Wine, no de Pash (comprobado con el buscador de Github). Todavía no he reportado ningún bug porque tengo que asegurarme de qué consideran bugs y qué no en el equipo de desarrollo de Wine.

Sea como sea, parecen buenas noticias que funcione así de bien a la primera, las funcionalidades que he probado son:

  • Variables locales
  • Constantes globales de valores de verdad
  • Asignaciones
  • Comparaciones entre números
  • Operadores numéricos básicos
  • Operadores booleanos básicos
  • Llamadas simples a programas
  • Impresiones por pantalla
  • Ejecución de scripts simples externos.
  • Condicionales simples if-else .

Saludos!

P.D.: Agradeceré enormemente a quien se anime e integre Pash en Wine! xD.

Ahora es más fácil desarrollar con Mono

Buenas 🙂 ,

parece que desde hace unas semanas el equipo de Xamarin se ha puesto las pilas y ha levantado repositorios públicos de paquetes para distintas distribuciones Linux, con lo que se ha facilitado bastante el desarrollo con las últimas versiones de Mono y Monodevelop (por ejemplo, yo tuve que compilar Mono y Monodevelop para poder trabajar cómodamente en el desarrollo de ColorSharp).

Hay repositorios para: Debian y derivados (como Ubuntu); Redhat, CentOS y Fedora; y también para SuSe y SLES.

Aquí está la página donde explican el proceso en pocos pasos para cada distribución: http://www.monodevelop.com/download/linux/ .

Además de los últimos paquetes de Mono y Monodevelop, también proveen el gestor de dependencias NuGet. Echo en falta que añadan también paquetes de Pash (un clon libre de PowerShell) en el repositorio, pero sigue siendo un gran paso.

Sobre NuGet y Pash

La dependencia que tiene ColorSharp de NuGet es casi evidente para los desarrolladores habituales de .NET. Por el momento solo distribuyo paquetes NuGet (todavía queda pendiente crear paquetes específicos para distribuciones Linux) y por otro lado también lo uso para obtener las dependencias de ColorSharp.

Pash no es tan importante para el trabajo que estoy desarrollando actualmente, pero cabe la posibilidad de que llegue a serlo. Desgraciadamente NuGet permite que sus paquetes incorporen scripts de PowerShell que se ejecutan durante (o al final de) el proceso de instalación. Esto hace que sea más complicado conseguir que nuestro código sea realmente multiplataforma si por casualidad cometemos el error de usar como dependencia uno de esos paquetes malditos.

De hecho, Monodevelop incorpora una versión modificada de Pash para mejorar la integración del IDE con NuGet (que aunque supuestamente bajo el auspicio de la fundación Outercurve, su desarrollo está demasiado ligado al de Microsoft Visual Studio).

 Otro problema que sigue pendiente en NuGet es que no da soporte a la operación ‘pack’ en entornos Linux (y creo que tampoco en Mac OS X, pero no lo puedo probar). Esta operación es la que se usa para crear los paquetes que he mencionado anteriormente. Esto no hace que ColorSharp sea menos libre ya que se pueden compilar los binarios a partir del código fuente usando solo herramientas libres, sin embargo está claro que dificulta y hace más incómodas ciertas tareas básicas del desarrollo de software.

Lo dicho, NuGet APESTA. El acoplamiento que existe entre esta herramienta y MS Visual Studio es horroroso, y cuando uno intenta hacer cosas ligeramente sofisticadas se encuentra con que son imposibles o se tienen que tocar a mano ficheros generados (y modificados) de forma automática, lo cual es una mala idea a todas luces. PIP, Gem, Composer, NPM, Bower y muchos otros sistemas del estilo le dan mil vueltas a NuGet. Esta gente no sabe trabajar con la comunidad.

Sobre compatibilidad cruzada

A lo largo del desarrollo he realizado algunos experimentos interesantes. Hasta el momento he conseguido ejecutar programas compilados en Windows (que usan ColorSharp como dependencia) en Linux a través de Wine; y viceversa, he podido ejecutar esos mismos programas compilados en Linux dentro de Windows a través de Cygwin. No he conseguido hacer funcionar el programa dentro de cygwin dentro de wine, ni dentro de wine dentro de cygwin: una lástima, habría sido divertido.

También he experimentado con NuGet dentro de Wine. No he conseguido nada debido a la dependencia de PowerShell. Sería bonito que Wine hiciera con Pash lo mismo que hizo con Mono, usar el proyecto libre para suplantar a la versión privativa y nativa de Windows, sin embargo no es así. Añado que ReactOS tampoco está por la labor 😦 , tienen problemas mucho más graves que resolver.

Slow progress, but still advancing

Hi!

ColorSharp development has stalled in recent weeks, but there are minor improvements that deserve mentioning. In few words, there is more flexibility.

  • There are new constructors in the RegularLightSpectrum class.
  • Added HashCode and Equals methods to the spectrum classes, this is a requirement to make possible using spectrum instances in dictionaries and other similar data structures.
  • Minor (not significant) performance improvements.
  • Updated MathNet.Numerics dependency.

In a few days I’ll start again providing improvements to the library. In recent posts I’ve talked about performance, but I’ll prioritize architecture improvements (towards objects immutability and common interfaces implementation) and colour features extraction.

A little dose of statistics

ColorSharp's NuGet StatisticsSo, there aren’t many interesting news today, but i want to share some bits of information about ColorSharp’s usage 🙂 .

I don’t know who is using it, but I’m sure that I’m not its unique user 😀 . Since the 0.5.2 version there are a lot of downloads that I can’t explain with my own use cases!

I’m happy because this project it’s still in alpha state, but there are people who are using it. The bad point is that nobody have still forked the project, nor starred it or marked it as ‘watching’ in Github. Obviously no one has sent any pull request 😦 .

Another important point is that I’ll have to stabilize soon the ColorSharp’s API to avoid irritating other programmers. The «playing time» is coming to an end.

If you want to contribute, feel free to do it 😉 , and if you have doubts, feel free to ask me too!

Microsoft makes .NET an open source project

Great news! After many years Microsoft has started a process to make .NET (and a lot of its many subprojects) an open source project 🙂 . More info in Miguel de Icaza’s blog : http://tirania.org/blog/archive/2014/Nov-12.html .

In my opinion, making .NET an open source project is not enough, but it’s a big step. We still need a better and more interoperable tool set: Last Mono version installers for Windows, better support for Linux in NuGet, more and better documentation for GTK#, a port of GTK# 3 to Windows (we are sill using GTK# 2.12), RYU‘s JIT SIMD classes in Mono

Mono shouldn’t the main desktop technology in Linux (as Miguel de Icaza pretended), but it’s a good open source project and it lacks the community support that deserves.

Mejorando el rendimiento de ColorSharp

Estos últimos días he realizado algunos cambios importantes en ColorSharp, aunque no han repercutido demasiado en su funcionalidad. He cambiado ligeramente la arquitectura subyacente, he añadido algo de documentación, TODOs, CHANGELOGs… Sin embargo lo que me motivó para realizar los cambios que me llevaron al cambio de arquitectura fue la búsqueda de un mayor rendimiento.

La realidad es que las mejoras que obtuve fueron marginales. No he tomado medidas (os prometo que la próxima vez seré más serio), pero puedo asegurar que la conversión de unas 40.000 muestras de color CIE XYZ a sRGB (que en mi máquina tomaba un segundo y medio aproximadamente) presentaba cambios difícilmente perceptibles por un ser humano.

Cambios planteados

SIMD

El primer cambio que me planteé fue introducir paralelismo a nivel de instrucción (SIMD) en los algoritmos. Había leído hace tiempo que Mono facilitaba el uso de SIMD sin necesidad de usar código inseguro, y eso fue lo que me incentivó a buscar. Desgraciadamente tuve que abandonar este enfoque, pues el diablo está en los detalles.

La versión «original» de .NET no permite usar SIMD, o no lo permitía hasta hace muy poco. Recientemente han creado «RyuJIT», que facilita el uso de SIMD… pero que presenta dos problemas: Es semiexperimental y su API para trabajar con SIMD es diferente a la que presentaba Mono. Por otro lado, parece que las versiones recientes de Mono para entornos de escritorio han eliminado el soporte de SIMD.

Algoritmo de Strassen

Una parte sustancial del cómputo realizado para convertir espacios de colores son productos de matrices. El algoritmo clásico de multiplicación de matrices toma un tiempo del orden O(n³) siendo n·n las dimensiones de la matriz. El algoritmo de Strassen se basa en un inteligente truco (basado en una observación de Gauss) que permite reducir ligeramente la complejidad asintótica del algoritmo. Aun no he aplicado esta optimización, sin embargo no espero una gran mejora, pues trabajo con n pequeña (generalmente 3).

Cambio de arquitectura

Este es el único cambio de la lista que ya he realizado a día de hoy. Consistió básicamente en reducir el uso de «Generics» y métodos «introspection/reflection», así como hardcodear los mejores caminos de conversión entre espacios de color en vez de calcularlos en tiempo de ejecución.

Aunque este cambio no presentó cambios notables, es el que permite un mejor aprovechamiento de las futuras mejoras que incorporen las VMs/JITs de .NET y Mono.

Aprovechar la GPU con OpenCL

Cuando pensé en usar SIMD también pensé en aprovechar la GPU, sin embargo mi desconocimiento en este campo frenó mi avance en esta dirección. Casualmente esta mañana he encontrado información muy útil que seguramente llevará a que en breve ColorSharp sea mucho más eficiente 🙂 .

Mi plan es usar OpenCL.NET (que funciona en Windows, Linux y Mac, tanto en .NET como en Mono). En cuanto a como aprenderé a usarlo en condiciones, he encontrado este tutorial, parece que promete bastante.

Futuros artículos

Puede que parezca raro tener en cuenta los artículos divulgativos en la lista de tareas pendientes, pero considero que es una parte esencial del proyecto.

Siguen pendientes los artículos sobre .NET, Mono, NuGet, PowerShell, PASH, Chocolatey… (también hablaré de Wine!). Como avance, tratarán sobre el ecosistema de software libre alrededor de Mono, especialmente sobre sus puntos débiles.

Además, hay otros dos puntos muy importantes que deben ser tratados: Qué motiva el desarrollo de ColorSharp y qué lo diferencia del resto de bibliotecas; y cómo preparar un desarrollo Mono para poder usar un entorno de CI (Continuous Integration).