Trabalho I: Multiplicação de Matrizes

Objectivo

O objectivo principal deste trabalho é fornecer aos alunos um primeiro contacto com programação avançada em UNIX tendo como base a linguagem C. Em particular, pretende-se que os alunos sejam capazes de lidar com argumentos passados através da linha de comando e com chamadas de sistema para manipulação de processos, tais como: fork(), pipe(), dup2(), exec(), wait(), exit(), entre outras.

Trabalho

O trabalho é composto por 3 etapas independentes que no conjunto levarão à implementação de uma mini linha de comandos para multiplicação de matrizes de inteiros. O produto final do trabalho deve ser um conjunto de 3 programas, cada um implementando cada uma das etapas. Segue-se a descrição das várias etapas do trabalho.

Etapa 1: vecmult

Crie um programa de nome vecmult para multiplicar um vector de inteiros por uma matriz de inteiros. O programa deverá aceitar como argumento o nome do ficheiro contendo a descrição da matriz e deverá receber do stdin a descrição do vector. O resultado da multiplicação do vector pela matriz deverá ser enviado para o stdout.

O ficheiro com a descrição da matriz deverá seguir o formato que se segue:


L C
M11 M12 ... M1C
M21 M22 ... M2C
...
ML1 ML2 ... MLC

em que os dois primeiros valores indicam respectivamente o número de linhas (L > 0) e colunas (C > 0) da matriz e os restantes valores indicam o conteúdo da matriz (Mij). Por sua vez a descrição do vector deverá seguir o seguinte formato:


V1 V2 ... VL

Por exemplo, considere dois ficheiros matrix.dat e vector.dat respectivamente com os seguintes conteúdos:


4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5

e


1 1 1 1

Sendo assim a execução do comando vecmult matrix.dat < vector.dat deverá devolver o seguinte resultado:


4 8 12 16 20

Como simplicação evite a detecção de erros e considere que os dados relativos ao vector e à matriz são sempre válidos e compatíveis (o tamanho do vector é igual ao número de linhas da matriz). Para ler a informação da matriz e do vector poderá utilizar as funções da família scanf().

Etapa 2: matmult

Crie um programa de nome matmult para multiplicar duas matrizes de inteiros. O programa deverá aceitar como argumentos o nome dos ficheiros contendo a descrição das matrizes e deverá enviar o resultado da multiplicação para o stdout. A execução do programa deverá ser algo da forma matmult matrixA.dat matrixB.dat, em que os ficheiros com a descrição das matrizes seguem o formato da etapa anterior.

Para calcular a matriz resultado, o programa matmult deverá criar tantos processos filho quantas as linhas da 1ª matriz. Por seu lado, cada processo filho deverá executar o programa vecmult da etapa anterior de modo a calcular uma das linhas da matriz resultado. O programa vecmult deverá ser executado através da utilização de uma das funções da família exec(), enquanto que a comunicação entre o programa matmult e os diversos filhos vecmult deverá ser conseguido por utilização de pipes.

Como simplicação evite a detecção de erros e considere que os dados relativos às matrizes são sempre válidos e compatíveis (neste caso o número de colunas da 1ª matriz deverá ser igual ao número de linhas da 2ª matriz). A leitura das linhas da 1ª matriz poderá ser feita utilizando a função getline().

Etapa 3: shellmult

Crie um programa de nome shellmult que implemente uma mini linha de comandos para multiplicação de matrizes (use o exercício da aula prática Exercícios II como referência para implementar o tratamento da linha de comandos). O programa deverá aceitar os comandos que se seguem: Possíveis erros de sintaxe ou de semântica na invocação dos comandos devem ser detectados e reportados para o stderr tal como se indica a seguir.

Prazos

O trabalho deve ser entregue via web até às 12 horas do dia 20 de Abril de 2009, sendo a sua demonstração feita na aula prática imediatamente a seguir.

O que entregar? Um ficheiro .tar que inclua:

O código deve compilar e executar nas máquinas da sala das aulas práticas. Uma boa estruturação e legibilidade do código será valorizada.